summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Kosiński <krzysio@google.com>2022-11-14 21:59:57 +0000
committerKrzysztof Kosiński <krzysio@google.com>2022-11-14 22:33:26 +0000
commit93d935569c800571f46055ec80fdfabf2936e4c7 (patch)
tree0712b54ff126833daf3c0411d54d54dff91d93d3
parent502f693808ea22d4ea3c611003779a31659ce5e3 (diff)
parent2c6decdfa7bedc671254da491bd34084332d30b0 (diff)
downloadow2-asm-93d935569c800571f46055ec80fdfabf2936e4c7.tar.gz
Import ASM 9.4.
Only add required Android files and licensing information for now. Build support will be added in the next CL. Bug: 259136464 Test: N/A Change-Id: I31299f29cb1e8e98455b46e00a4ad3de43f75ee1
-rw-r--r--.gitignore14
-rw-r--r--.gitlab-ci.yml21
-rw-r--r--.gitlab/issue_templates/default.md42
-rw-r--r--.mailmap8
-rw-r--r--Android.bp9
l---------LICENSE1
-rw-r--r--LICENSE.txt28
-rw-r--r--METADATA17
-rw-r--r--MODULE_LICENSE_BSD0
-rw-r--r--OWNERS7
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java691
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/AnalyzerException.java89
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java375
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java129
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java450
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java752
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Interpreter.java267
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java381
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java198
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java220
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java119
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Subroutine.java106
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Value.java44
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/package.html69
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java1274
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java256
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicVerifierTest.java243
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSimpleVerifierTest.java201
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSourceInterpreterTest.java71
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicValueTest.java80
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/MethodNodeBuilder.java227
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java135
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SmallSetTest.java171
-rw-r--r--asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SourceValueTest.java72
-rw-r--r--asm-analysis/src/test/resources/Issue316204.classbin0 -> 4594 bytes
-rw-r--r--asm-analysis/src/test/resources/sigtest-4.0.txt436
-rw-r--r--asm-analysis/src/test/resources/sigtest-5.0.txt440
-rw-r--r--asm-analysis/src/test/resources/sigtest-6.0.txt430
-rw-r--r--asm-analysis/src/test/resources/sigtest-6.1.txt433
-rw-r--r--asm-analysis/src/test/resources/sigtest-7.0.txt443
-rw-r--r--asm-analysis/src/test/resources/sigtest-7.2.txt447
-rw-r--r--asm-analysis/src/test/resources/sigtest-7.3.1.txt448
-rw-r--r--asm-analysis/src/test/resources/sigtest-8.0.1.txt450
-rw-r--r--asm-analysis/src/test/resources/sigtest-9.0.txt452
-rw-r--r--asm-analysis/src/test/resources/sigtest-9.1.txt454
-rw-r--r--asm-analysis/src/test/resources/sigtest-9.2.txt455
-rw-r--r--asm-analysis/src/test/resources/sigtest-9.4.txt458
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/AdviceAdapter.java670
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java910
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java210
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java300
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java207
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java115
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java1369
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java1303
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java572
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java351
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/Method.java262
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java290
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/ModuleHashesAttribute.java139
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java121
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/ModuleResolutionAttribute.java113
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/ModuleTargetAttribute.java87
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java118
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java385
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java492
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java173
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java104
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java124
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/TableSwitchGenerator.java51
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java126
-rw-r--r--asm-commons/src/main/java/org/objectweb/asm/commons/package.html52
-rw-r--r--asm-commons/src/resources/java/SerialVersionAnonymousInnerClass.java45
-rw-r--r--asm-commons/src/resources/java/SerialVersionClass.java50
-rw-r--r--asm-commons/src/resources/java/SerialVersionEmptyInterface.java35
-rw-r--r--asm-commons/src/resources/java/SerialVersionEnum.java37
-rw-r--r--asm-commons/src/resources/java/SerialVersionInterface.java37
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java843
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java323
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java425
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/CodeComment.java84
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/CodeSizeEvaluatorTest.java161
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/Comment.java72
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java1259
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java299
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/JsrInlinerAdapterTest.java1539
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java248
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/MethodNodeBuilder.java267
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java133
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java85
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java69
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java68
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java106
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/SimpleRemapperTest.java88
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/StaticInitMergerTest.java83
-rw-r--r--asm-commons/src/test/java/org/objectweb/asm/commons/TryCatchBlockSorterTest.java94
-rw-r--r--asm-commons/src/test/resources/Issue317586.classbin0 -> 1112 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionAnonymousInnerClass$1.classbin0 -> 400 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionAnonymousInnerClass.classbin0 -> 611 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionClass.classbin0 -> 458 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionEmptyInterface.classbin0 -> 163 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionEnum.classbin0 -> 998 bytes
-rw-r--r--asm-commons/src/test/resources/SerialVersionInterface.classbin0 -> 199 bytes
-rw-r--r--asm-commons/src/test/resources/sigtest-4.0.txt747
-rw-r--r--asm-commons/src/test/resources/sigtest-4.1.txt750
-rw-r--r--asm-commons/src/test/resources/sigtest-5.0.4.txt782
-rw-r--r--asm-commons/src/test/resources/sigtest-5.0.txt781
-rw-r--r--asm-commons/src/test/resources/sigtest-5.1.txt863
-rw-r--r--asm-commons/src/test/resources/sigtest-6.0.txt988
-rw-r--r--asm-commons/src/test/resources/sigtest-6.1.txt966
-rw-r--r--asm-commons/src/test/resources/sigtest-6.2.txt968
-rw-r--r--asm-commons/src/test/resources/sigtest-7.0.txt977
-rw-r--r--asm-commons/src/test/resources/sigtest-7.1.txt965
-rw-r--r--asm-commons/src/test/resources/sigtest-7.2.txt966
-rw-r--r--asm-commons/src/test/resources/sigtest-7.3.1.txt994
-rw-r--r--asm-commons/src/test/resources/sigtest-8.0.1.txt997
-rw-r--r--asm-commons/src/test/resources/sigtest-9.0.txt1001
-rw-r--r--asm-commons/src/test/resources/sigtest-9.1.txt1012
-rw-r--r--asm-commons/src/test/resources/sigtest-9.2.txt1013
-rw-r--r--asm-commons/src/test/resources/sigtest-9.4.txt1021
-rw-r--r--asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java389
-rw-r--r--asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java2637
-rw-r--r--asm-test/src/main/java/org/objectweb/asm/test/ClassFormatException.java30
-rw-r--r--asm-test/src/main/java/org/objectweb/asm/test/Util.java53
-rw-r--r--asm-test/src/main/resources/DefaultPackage.classbin0 -> 109 bytes
-rw-r--r--asm-test/src/main/resources/annotations/ICA.classbin0 -> 392 bytes
-rw-r--r--asm-test/src/main/resources/annotations/IFA.classbin0 -> 386 bytes
-rw-r--r--asm-test/src/main/resources/annotations/IMA.classbin0 -> 387 bytes
-rw-r--r--asm-test/src/main/resources/annotations/IPA.classbin0 -> 390 bytes
-rw-r--r--asm-test/src/main/resources/annotations/ITA.classbin0 -> 385 bytes
-rw-r--r--asm-test/src/main/resources/annotations/ITPA.classbin0 -> 397 bytes
-rw-r--r--asm-test/src/main/resources/annotations/ITUA.classbin0 -> 391 bytes
-rw-r--r--asm-test/src/main/resources/annotations/IVA.classbin0 -> 395 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VCA.classbin0 -> 394 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VFA.classbin0 -> 388 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VMA.classbin0 -> 389 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VPA.classbin0 -> 392 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VTA.classbin0 -> 387 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VTPA.classbin0 -> 399 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VTUA.classbin0 -> 393 bytes
-rw-r--r--asm-test/src/main/resources/annotations/VVA.classbin0 -> 397 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidBytecodeOffset.clazzbin0 -> 334 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidClassVersion.clazzbin0 -> 220 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidCodeLength.clazzbin0 -> 323 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidConstantPoolIndex.clazzbin0 -> 230 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidConstantPoolReference.clazzbin0 -> 238 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidCpInfoTag.clazzbin0 -> 214 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidElementValue.clazzbin0 -> 305 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidInsnTypeAnnotationTargetType.clazzbin0 -> 381 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidOpcode.clazzbin0 -> 208 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidSourceDebugExtension.clazzbin0 -> 277 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidStackMapFrameType.clazzbin0 -> 415 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidTypeAnnotationTargetType.clazzbin0 -> 348 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidVerificationTypeInfo.clazzbin0 -> 421 bytes
-rw-r--r--asm-test/src/main/resources/invalid/InvalidWideOpcode.clazzbin0 -> 277 bytes
-rw-r--r--asm-test/src/main/resources/jdk11/AllInstructions.classbin0 -> 1444 bytes
-rw-r--r--asm-test/src/main/resources/jdk11/AllStructures$Nested.classbin0 -> 234 bytes
-rw-r--r--asm-test/src/main/resources/jdk11/AllStructures.classbin0 -> 232 bytes
-rw-r--r--asm-test/src/main/resources/jdk14/AllStructures$EmptyRecord.classbin0 -> 1106 bytes
-rw-r--r--asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.classbin0 -> 2201 bytes
-rw-r--r--asm-test/src/main/resources/jdk15/AllStructures.classbin0 -> 320 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk3/AllInstructions.classbin0 -> 6848 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk3/AllStructures$1.classbin0 -> 828 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk3/AllStructures$InnerClass.classbin0 -> 876 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk3/AllStructures.classbin0 -> 2225 bytes
-rw-r--r--asm-test/src/main/resources/jdk3/ArtificialStructures.classbin0 -> 771 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk3/LargeMethod.classbin0 -> 39299 bytes
-rw-r--r--asm-test/src/main/resources/jdk3/SubOptimalMaxStackAndLocals.classbin0 -> 203 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllInstructions.classbin0 -> 6605 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures$1LocalClass.classbin0 -> 1132 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures$EnumClass.classbin0 -> 1284 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures$GenericInnerClass.classbin0 -> 648 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures$InnerClass.classbin0 -> 552 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures$InvisibleAnnotation.classbin0 -> 1764 bytes
-rwxr-xr-xasm-test/src/main/resources/jdk5/AllStructures.classbin0 -> 5279 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/AllFrames.classbin0 -> 5092 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/AllInstructions.classbin0 -> 1903 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/AllStructures$1.classbin0 -> 1178 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/AllStructures$InnerClass.classbin0 -> 1135 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/AllStructures.classbin0 -> 4569 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/Artificial$()$Structures.classbin0 -> 502 bytes
-rw-r--r--asm-test/src/main/resources/jdk8/LargeMethod.classbin0 -> 34364 bytes
-rw-r--r--asm-test/src/main/resources/jdk9/module-info.classbin0 -> 394 bytes
-rw-r--r--asm-test/src/main/resources/jdk9/pkg/A.classbin0 -> 251 bytes
-rw-r--r--asm-test/src/main/resources/jdk9/pkg/internal/AImpl.classbin0 -> 186 bytes
-rw-r--r--asm-test/src/resources/java/DefaultPackage.java30
-rw-r--r--asm-test/src/resources/java/annotations/ICA.java40
-rw-r--r--asm-test/src/resources/java/annotations/IFA.java40
-rw-r--r--asm-test/src/resources/java/annotations/IMA.java40
-rw-r--r--asm-test/src/resources/java/annotations/IPA.java40
-rw-r--r--asm-test/src/resources/java/annotations/IRCA.java40
-rw-r--r--asm-test/src/resources/java/annotations/ITA.java40
-rw-r--r--asm-test/src/resources/java/annotations/ITPA.java40
-rw-r--r--asm-test/src/resources/java/annotations/ITUA.java40
-rw-r--r--asm-test/src/resources/java/annotations/IVA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VCA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VFA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VMA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VPA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VRCA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VTA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VTPA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VTUA.java40
-rw-r--r--asm-test/src/resources/java/annotations/VVA.java40
-rw-r--r--asm-test/src/resources/java/invalid/InvalidBytecodeOffset.java37
-rw-r--r--asm-test/src/resources/java/invalid/InvalidClassVersion.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidCodeLength.java37
-rw-r--r--asm-test/src/resources/java/invalid/InvalidConstantPoolIndex.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidConstantPoolReference.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidCpInfoTag.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidElementValue.java34
-rw-r--r--asm-test/src/resources/java/invalid/InvalidInsnTypeAnnotationTargetType.java44
-rw-r--r--asm-test/src/resources/java/invalid/InvalidOpcode.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidSourceDebugExtension.java30
-rw-r--r--asm-test/src/resources/java/invalid/InvalidStackMapFrameType.java37
-rw-r--r--asm-test/src/resources/java/invalid/InvalidTypeAnnotationTargetType.java42
-rw-r--r--asm-test/src/resources/java/invalid/InvalidVerificationTypeInfo.java37
-rw-r--r--asm-test/src/resources/java/invalid/InvalidWideOpcode.java36
-rw-r--r--asm-test/src/resources/java/jdk11/AllInstructions.jasm119
-rw-r--r--asm-test/src/resources/java/jdk11/AllStructures$Nested.jasm53
-rw-r--r--asm-test/src/resources/java/jdk11/AllStructures.jasm53
-rw-r--r--asm-test/src/resources/java/jdk14/AllStructures.java47
-rw-r--r--asm-test/src/resources/java/jdk15/AllStructures.java37
-rwxr-xr-xasm-test/src/resources/java/jdk3/AllInstructions.java285
-rwxr-xr-xasm-test/src/resources/java/jdk3/AllStructures.java117
-rw-r--r--asm-test/src/resources/java/jdk3/DumpArtificialStructures.java180
-rwxr-xr-xasm-test/src/resources/java/jdk3/LargeMethod.java536
-rw-r--r--asm-test/src/resources/java/jdk3/SubOptimalMaxStackAndLocals.jasm50
-rwxr-xr-xasm-test/src/resources/java/jdk5/AllInstructions.java288
-rwxr-xr-xasm-test/src/resources/java/jdk5/AllStructures.java225
-rwxr-xr-xasm-test/src/resources/java/jdk8/AllFrames.java221
-rwxr-xr-xasm-test/src/resources/java/jdk8/AllInstructions.java45
-rwxr-xr-xasm-test/src/resources/java/jdk8/AllStructures.java152
-rw-r--r--asm-test/src/resources/java/jdk8/DumpArtificialStructures.java132
-rw-r--r--asm-test/src/resources/java/jdk8/LargeMethod.java400
-rw-r--r--asm-test/src/resources/java/jdk9/META-INF/MANIFEST.MF4
-rw-r--r--asm-test/src/resources/java/jdk9/pkg/module-info.java43
-rw-r--r--asm-test/src/resources/java/jdk9/pkg/pkg/A.java34
-rw-r--r--asm-test/src/resources/java/jdk9/pkg/pkg/internal/AImpl.java31
-rw-r--r--asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java110
-rw-r--r--asm-test/src/test/java/org/objectweb/asm/test/ClassFileTest.java152
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/AbstractInsnNode.java269
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java230
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java472
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/FieldInsnNode.java96
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java244
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/FrameNode.java192
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/IincInsnNode.java74
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/InnerClassNode.java91
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java604
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/InsnNode.java73
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/IntInsnNode.java79
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/InvokeDynamicInsnNode.java92
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/JumpInsnNode.java87
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LabelNode.java79
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LdcInsnNode.java83
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LineNumberNode.java74
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java140
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableNode.java92
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/LookupSwitchInsnNode.java93
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/MethodInsnNode.java123
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java772
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java83
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java245
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java82
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java69
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ModuleRequireNode.java73
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/MultiANewArrayInsnNode.java74
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/ParameterNode.java68
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/RecordComponentNode.java204
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/TableSwitchInsnNode.java93
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/TryCatchBlockNode.java127
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java85
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/TypeInsnNode.java85
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/UnsupportedClassVersionException.java14
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/Util.java163
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/VarInsnNode.java82
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/package.html197
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java123
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java249
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/CodeComment.java77
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/Comment.java72
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/FieldInsnNodeTest.java62
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/FieldNodeTest.java59
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/FrameNodeTest.java65
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/IincInsnNodeTest.java50
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java973
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/InsnNodeTest.java50
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/IntInsnNodeTest.java59
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/InvokeDynamicInsnNodeTest.java59
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/JumpInsnNodeTest.java62
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/LabelNodeTest.java55
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/LdcInsnNodeTest.java49
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/LineNumberNodeTest.java52
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/LookupSwitchInsnNodeTest.java56
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/MethodInsnNodeTest.java83
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/MethodNodeTest.java120
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java99
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/MultiANewArrayInsnNodeTest.java50
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/RecordComponentNodeTest.java58
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/TableSwitchInsnNodeTest.java56
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/TypeAnnotationNodeTest.java64
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/TypeInsnNodeTest.java60
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/UtilTest.java76
-rw-r--r--asm-tree/src/test/java/org/objectweb/asm/tree/VarInsnNodeTest.java60
-rw-r--r--asm-tree/src/test/resources/sigtest-4.0.txt442
-rw-r--r--asm-tree/src/test/resources/sigtest-5.0.txt503
-rw-r--r--asm-tree/src/test/resources/sigtest-6.0.txt576
-rw-r--r--asm-tree/src/test/resources/sigtest-6.1.txt627
-rw-r--r--asm-tree/src/test/resources/sigtest-7.0.txt633
-rw-r--r--asm-tree/src/test/resources/sigtest-7.1.txt632
-rw-r--r--asm-tree/src/test/resources/sigtest-7.2.txt638
-rw-r--r--asm-tree/src/test/resources/sigtest-7.3.1.txt659
-rw-r--r--asm-tree/src/test/resources/sigtest-8.0.1.txt672
-rw-r--r--asm-tree/src/test/resources/sigtest-9.0.txt675
-rw-r--r--asm-tree/src/test/resources/sigtest-9.1.txt675
-rw-r--r--asm-tree/src/test/resources/sigtest-9.2.txt675
-rw-r--r--asm-tree/src/test/resources/sigtest-9.4.txt680
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java1612
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/ASMifierSupport.java45
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java135
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java1137
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java116
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckFrameAnalyzer.java477
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java1483
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java212
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckRecordComponentAdapter.java121
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java359
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/Printer.java1310
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/Textifier.java1604
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TextifierSupport.java41
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java93
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java244
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java93
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java312
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java111
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceRecordComponentVisitor.java96
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java344
-rw-r--r--asm-util/src/main/java/org/objectweb/asm/util/package.html44
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java225
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java96
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java664
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckFieldAdapterTest.java86
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckFrameAnalyzerTest.java369
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java1245
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckModuleAdapterTest.java179
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckRecordComponentAdapterTest.java86
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CheckSignatureAdapterTest.java525
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java92
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/Comment.java92
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/MethodNodeBuilder.java109
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java541
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java96
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/TextifierTest.java202
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/TraceClassVisitorTest.java139
-rw-r--r--asm-util/src/test/java/org/objectweb/asm/util/TraceSignatureVisitorTest.java186
-rw-r--r--asm-util/src/test/resources/DefaultPackage.txt6
-rw-r--r--asm-util/src/test/resources/jdk11.AllInstructions.txt57
-rw-r--r--asm-util/src/test/resources/jdk11.AllStructures$Nested.txt15
-rw-r--r--asm-util/src/test/resources/jdk11.AllStructures.txt15
-rw-r--r--asm-util/src/test/resources/jdk14.AllStructures$EmptyRecord.txt71
-rw-r--r--asm-util/src/test/resources/jdk14.AllStructures$RecordSubType.txt147
-rw-r--r--asm-util/src/test/resources/jdk15.AllStructures.txt14
-rw-r--r--asm-util/src/test/resources/jdk3.AllInstructions.txt1714
-rw-r--r--asm-util/src/test/resources/jdk3.AllStructures$1.txt62
-rw-r--r--asm-util/src/test/resources/jdk3.AllStructures$InnerClass.txt69
-rw-r--r--asm-util/src/test/resources/jdk3.AllStructures.txt252
-rw-r--r--asm-util/src/test/resources/jdk3.ArtificialStructures.txt101
-rw-r--r--asm-util/src/test/resources/jdk3.SubOptimalMaxStackAndLocals.txt14
-rw-r--r--asm-util/src/test/resources/jdk5.AllInstructions.txt1695
-rw-r--r--asm-util/src/test/resources/jdk5.AllStructures$1LocalClass.txt55
-rw-r--r--asm-util/src/test/resources/jdk5.AllStructures$EnumClass.txt136
-rw-r--r--asm-util/src/test/resources/jdk5.AllStructures$InvisibleAnnotation.txt111
-rw-r--r--asm-util/src/test/resources/jdk5.AllStructures.txt297
-rw-r--r--asm-util/src/test/resources/jdk8.AllFrames.txt951
-rw-r--r--asm-util/src/test/resources/jdk8.AllInstructions.txt103
-rw-r--r--asm-util/src/test/resources/jdk8.AllStructures$1.txt75
-rw-r--r--asm-util/src/test/resources/jdk8.AllStructures$InnerClass.txt76
-rw-r--r--asm-util/src/test/resources/jdk8.AllStructures.txt294
-rw-r--r--asm-util/src/test/resources/jdk8.Artificial$()$Structures.txt56
-rw-r--r--asm-util/src/test/resources/jdk9.module-info.txt27
-rw-r--r--asm-util/src/test/resources/sigtest-4.0.txt477
-rw-r--r--asm-util/src/test/resources/sigtest-4.1.txt480
-rw-r--r--asm-util/src/test/resources/sigtest-5.0.txt532
-rw-r--r--asm-util/src/test/resources/sigtest-6.0.txt608
-rw-r--r--asm-util/src/test/resources/sigtest-6.1.txt618
-rw-r--r--asm-util/src/test/resources/sigtest-7.0.txt631
-rw-r--r--asm-util/src/test/resources/sigtest-7.1.txt642
-rw-r--r--asm-util/src/test/resources/sigtest-7.2.txt633
-rw-r--r--asm-util/src/test/resources/sigtest-7.3.1.txt660
-rw-r--r--asm-util/src/test/resources/sigtest-8.0.1.txt683
-rw-r--r--asm-util/src/test/resources/sigtest-9.0.txt689
-rw-r--r--asm-util/src/test/resources/sigtest-9.1.txt689
-rw-r--r--asm-util/src/test/resources/sigtest-9.2.txt689
-rw-r--r--asm-util/src/test/resources/sigtest-9.4.txt694
-rw-r--r--asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java168
-rw-r--r--asm/src/main/java/org/objectweb/asm/AnnotationWriter.java553
-rw-r--r--asm/src/main/java/org/objectweb/asm/Attribute.java392
-rw-r--r--asm/src/main/java/org/objectweb/asm/ByteVector.java373
-rw-r--r--asm/src/main/java/org/objectweb/asm/ClassReader.java3852
-rw-r--r--asm/src/main/java/org/objectweb/asm/ClassTooLargeException.java72
-rw-r--r--asm/src/main/java/org/objectweb/asm/ClassVisitor.java398
-rw-r--r--asm/src/main/java/org/objectweb/asm/ClassWriter.java1079
-rw-r--r--asm/src/main/java/org/objectweb/asm/ConstantDynamic.java178
-rw-r--r--asm/src/main/java/org/objectweb/asm/Constants.java221
-rw-r--r--asm/src/main/java/org/objectweb/asm/Context.java137
-rw-r--r--asm/src/main/java/org/objectweb/asm/CurrentFrame.java56
-rw-r--r--asm/src/main/java/org/objectweb/asm/Edge.java91
-rw-r--r--asm/src/main/java/org/objectweb/asm/FieldVisitor.java151
-rw-r--r--asm/src/main/java/org/objectweb/asm/FieldWriter.java284
-rw-r--r--asm/src/main/java/org/objectweb/asm/Frame.java1473
-rw-r--r--asm/src/main/java/org/objectweb/asm/Handle.java190
-rw-r--r--asm/src/main/java/org/objectweb/asm/Handler.java198
-rw-r--r--asm/src/main/java/org/objectweb/asm/Label.java622
-rw-r--r--asm/src/main/java/org/objectweb/asm/MethodTooLargeException.java99
-rw-r--r--asm/src/main/java/org/objectweb/asm/MethodVisitor.java799
-rw-r--r--asm/src/main/java/org/objectweb/asm/MethodWriter.java2394
-rw-r--r--asm/src/main/java/org/objectweb/asm/ModuleVisitor.java196
-rw-r--r--asm/src/main/java/org/objectweb/asm/ModuleWriter.java253
-rw-r--r--asm/src/main/java/org/objectweb/asm/Opcodes.java563
-rw-r--r--asm/src/main/java/org/objectweb/asm/RecordComponentVisitor.java153
-rw-r--r--asm/src/main/java/org/objectweb/asm/RecordComponentWriter.java225
-rw-r--r--asm/src/main/java/org/objectweb/asm/Symbol.java243
-rw-r--r--asm/src/main/java/org/objectweb/asm/SymbolTable.java1322
-rw-r--r--asm/src/main/java/org/objectweb/asm/Type.java895
-rw-r--r--asm/src/main/java/org/objectweb/asm/TypePath.java201
-rw-r--r--asm/src/main/java/org/objectweb/asm/TypeReference.java436
-rw-r--r--asm/src/main/java/org/objectweb/asm/package.html78
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/SignatureReader.java252
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java210
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java247
-rw-r--r--asm/src/main/java/org/objectweb/asm/signature/package.html40
-rw-r--r--asm/src/test/java/org/objectweb/asm/AnnotationVisitorTest.java300
-rw-r--r--asm/src/test/java/org/objectweb/asm/AttributeTest.java51
-rw-r--r--asm/src/test/java/org/objectweb/asm/ByteVectorTest.java192
-rw-r--r--asm/src/test/java/org/objectweb/asm/ClassReaderTest.java761
-rw-r--r--asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java692
-rw-r--r--asm/src/test/java/org/objectweb/asm/ClassWriterComputeMaxsTest.java1198
-rw-r--r--asm/src/test/java/org/objectweb/asm/ClassWriterTest.java1068
-rw-r--r--asm/src/test/java/org/objectweb/asm/CodeComment.java71
-rw-r--r--asm/src/test/java/org/objectweb/asm/Comment.java66
-rw-r--r--asm/src/test/java/org/objectweb/asm/ConstantsTest.java569
-rw-r--r--asm/src/test/java/org/objectweb/asm/FieldVisitorTest.java67
-rw-r--r--asm/src/test/java/org/objectweb/asm/HandleTest.java106
-rw-r--r--asm/src/test/java/org/objectweb/asm/HandlerTest.java153
-rw-r--r--asm/src/test/java/org/objectweb/asm/LabelTest.java73
-rw-r--r--asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java567
-rw-r--r--asm/src/test/java/org/objectweb/asm/MethodWriterTest.java134
-rw-r--r--asm/src/test/java/org/objectweb/asm/ModuleVisitorTest.java67
-rw-r--r--asm/src/test/java/org/objectweb/asm/RecordComponentVisitorTest.java67
-rw-r--r--asm/src/test/java/org/objectweb/asm/TypePathTest.java76
-rw-r--r--asm/src/test/java/org/objectweb/asm/TypeReferenceTest.java107
-rw-r--r--asm/src/test/java/org/objectweb/asm/TypeTest.java434
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java85
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignatureVisitorTest.java50
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java65
-rw-r--r--asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java111
-rw-r--r--asm/src/test/resources/Issue307600.classbin0 -> 102569 bytes
-rw-r--r--asm/src/test/resources/Issue311642.classbin0 -> 78303 bytes
-rw-r--r--asm/src/test/resources/sigtest-4.0.txt515
-rw-r--r--asm/src/test/resources/sigtest-5.0.txt584
-rw-r--r--asm/src/test/resources/sigtest-5.1.txt587
-rw-r--r--asm/src/test/resources/sigtest-6.0.txt617
-rw-r--r--asm/src/test/resources/sigtest-6.1.txt618
-rw-r--r--asm/src/test/resources/sigtest-6.2.txt629
-rw-r--r--asm/src/test/resources/sigtest-7.0.txt708
-rw-r--r--asm/src/test/resources/sigtest-7.1.txt711
-rw-r--r--asm/src/test/resources/sigtest-7.2.txt712
-rw-r--r--asm/src/test/resources/sigtest-7.3.1.txt729
-rw-r--r--asm/src/test/resources/sigtest-8.0.1.txt729
-rw-r--r--asm/src/test/resources/sigtest-9.0.txt733
-rw-r--r--asm/src/test/resources/sigtest-9.1.txt734
-rw-r--r--asm/src/test/resources/sigtest-9.2.txt735
-rw-r--r--asm/src/test/resources/sigtest-9.4.txt745
-rw-r--r--benchmarks/libs/csg-bytecode-1.0.0.jarbin0 -> 96679 bytes
-rw-r--r--benchmarks/libs/jclasslib.jarbin0 -> 519173 bytes
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java216
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Adapter.java147
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmark.java542
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmarkJava8.java258
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java447
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmFactory.java68
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmGenerator.java87
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelAdapter.java82
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelGenerator.java85
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelAdapter.java82
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelGenerator.java85
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CojenGenerator.java71
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CsgBytecodeGenerator.java71
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Factory.java59
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Generator.java52
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GeneratorBenchmark.java172
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GnuByteCodeGenerator.java76
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java143
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java57
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JiapiGenerator.java78
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryBenchmark.java190
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java152
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MozillaClassFileGenerator.java61
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/SerpAdapter.java61
-rw-r--r--benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java254
-rw-r--r--build.gradle442
-rwxr-xr-xgradle/gradlew160
-rw-r--r--gradle/gradlew.bat90
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin0 -> 53636 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties6
-rw-r--r--settings.gradle40
-rw-r--r--tools/checkstyle.xml149
-rw-r--r--tools/jdk8-api.jarbin0 -> 466045 bytes
-rw-r--r--tools/pmd.xml123
-rw-r--r--tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java491
-rw-r--r--tools/retrofitter/src/main/resources/jdk1.5.0.12.txt.gzbin0 -> 216924 bytes
512 files changed, 138909 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..cabac2e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+# Files generated by Gradle
+.gradle/
+build/
+
+# Files generated by Eclipse
+**/.classpath
+**/.project
+**/.settings/
+**/bin/
+
+# Files generated by IntelliJ
+.idea/
+out/
+*.iml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..0cfedfd9
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,21 @@
+image: gradle:7.4.1-jdk11
+
+variables:
+ # Set the location of the dependency cache to a local directory, so that it
+ # can be cached between GitLab Continous Integration Jobs.
+ GRADLE_USER_HOME: '.gradle'
+ GRADLE: 'gradle -Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m'
+ SONAR: 'https://sonarqube.ow2.org'
+
+cache:
+ paths:
+ # Cache the downloaded dependencies and plugins between builds.
+ - '$GRADLE_USER_HOME'
+
+build:
+ script:
+ - $GRADLE build
+ - $GRADLE test jacocoTestCoverageVerification
+ - if [ $NEXUS_USER_NAME ]; then $GRADLE publish; fi
+ - if [ !$NEXUS_USER_NAME ]; then $GRADLE publishToMavenLocal; fi
+ - if [ $SONAR_LOGIN ]; then $GRADLE jacocoTestReport sonarqube -Dsonar.host.url=$SONAR -Dsonar.login=${SONAR_LOGIN}; fi
diff --git a/.gitlab/issue_templates/default.md b/.gitlab/issue_templates/default.md
new file mode 100644
index 00000000..ab1ffdce
--- /dev/null
+++ b/.gitlab/issue_templates/default.md
@@ -0,0 +1,42 @@
+<!---
+Before creating a new issue, consider the following (this does not apply to
+feature requests):
+
+- if you need help on how to use ASM, please consult the documentation first
+(https://asm.ow2.io/documentation.html). If you can't find the answer there,
+describe your problem on the http://mail.ow2.org/wws/info/asm mailing listing
+instead of using GitLab issues. The mailing list has more subscribers than the
+GitLab issue tracker, and you will thus likely get a quicker answer via the
+mailing list.
+
+- check if your *input* classes are valid. For this you can use "javap -p -c -v
+<yourclass.class>". If this command fails, the bug is most likely in the tool
+that produced this class, not in ASM. Check the javap output carefully:
+sometimes the tool is able to print most of the class content, but fails to
+parse some part of it. In this case there can be an error message in the middle
+of the javap output, which can be easy to miss at first sight.
+
+- check if you are using the ASM API correctly. For this, insert one or more
+CheckClassAdapter instances in your class generation or class transformation
+chain (in particular, in front of ClassWriter instances). If a CheckClassAdapter
+throws an exception, this means that you are not using the ASM API correctly.
+Fix these issues first.
+
+If you still have a bug after completing the above steps, describe it below and
+make sure to provide detailed instructions on how to reproduce it.
+-->
+
+<!--- Provide a brief summary of the issue in the title above -->
+
+### Expected Behavior
+<!--- Tell us what should happen. -->
+
+### Current Behavior
+<!--- Tell us what happens instead of the expected behavior. -->
+
+### Steps to Reproduce
+<!---
+Provide a self-contained example as an attached archive. If the source code to
+reproduce the issue is very small you can include it here directly (with its
+inputs, most likely some binary .class files, as an attached archive).
+-->
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 00000000..fcf2beaa
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,8 @@
+# In alphabetical order of family name:
+Eric Bruneton <ebruneton>
+Sebastien Chassande-Barrioz <chassand>
+Remi Forax <forax>
+Remi Forax <forax@univ-mlv.fr>
+Eugene Kuleshov <ekuleshov>
+Andrei Loskutov <andrei>
+
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 00000000..c638bb88
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,9 @@
+package {
+ default_applicable_licenses: ["external_ow2_asm_license"],
+}
+
+license {
+ name: "external_ow2_asm_license",
+ license_kinds: ["SPDX-license-identifier-BSD-3-Clause"],
+ license_text: ["LICENSE.txt"],
+}
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 00000000..85de3d45
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE.txt \ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 00000000..4d191851
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,28 @@
+
+ ASM: a very small and fast Java bytecode manipulation framework
+ Copyright (c) 2000-2011 INRIA, France Telecom
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 00000000..ecd75791
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,17 @@
+name: "ow2-asm"
+description:
+ "Java bytecode manipulation and analysis framework"
+
+third_party {
+ url {
+ type: HOMEPAGE
+ value: "https://asm.ow2.io/"
+ }
+ url {
+ type: GIT
+ value: "https://gitlab.ow2.org/asm/asm.git"
+ }
+ version: "9.4"
+ last_upgrade_date { year: 2022 month: 11 day: 14 }
+ license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 00000000..59a1608d
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,7 @@
+krzysio@google.com
+allenhair@google.com
+hhb@google.com
+omakoto@google.com
+jiyong@google.com
+acleung@google.com
+ccross@android.com
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java
new file mode 100644
index 00000000..40432a5b
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Analyzer.java
@@ -0,0 +1,691 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.IincInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.VarInsnNode;
+
+/**
+ * A semantic bytecode analyzer. <i>This class does not fully check that JSR and RET instructions
+ * are valid.</i>
+ *
+ * @param <V> type of the {@link Value} used for the analysis.
+ * @author Eric Bruneton
+ */
+public class Analyzer<V extends Value> implements Opcodes {
+
+ /** The interpreter to use to symbolically interpret the bytecode instructions. */
+ private final Interpreter<V> interpreter;
+
+ /** The instructions of the currently analyzed method. */
+ private InsnList insnList;
+
+ /** The size of {@link #insnList}. */
+ private int insnListSize;
+
+ /** The exception handlers of the currently analyzed method (one list per instruction index). */
+ private List<TryCatchBlockNode>[] handlers;
+
+ /** The execution stack frames of the currently analyzed method (one per instruction index). */
+ private Frame<V>[] frames;
+
+ /** The subroutines of the currently analyzed method (one per instruction index). */
+ private Subroutine[] subroutines;
+
+ /** The instructions that remain to process (one boolean per instruction index). */
+ private boolean[] inInstructionsToProcess;
+
+ /** The indices of the instructions that remain to process in the currently analyzed method. */
+ private int[] instructionsToProcess;
+
+ /** The number of instructions that remain to process in the currently analyzed method. */
+ private int numInstructionsToProcess;
+
+ /**
+ * Constructs a new {@link Analyzer}.
+ *
+ * @param interpreter the interpreter to use to symbolically interpret the bytecode instructions.
+ */
+ public Analyzer(final Interpreter<V> interpreter) {
+ this.interpreter = interpreter;
+ }
+
+ /**
+ * Analyzes the given method.
+ *
+ * @param owner the internal name of the class to which 'method' belongs (see {@link
+ * Type#getInternalName()}).
+ * @param method the method to be analyzed. The maxStack and maxLocals fields must have correct
+ * values.
+ * @return the symbolic state of the execution stack frame at each bytecode instruction of the
+ * method. The size of the returned array is equal to the number of instructions (and labels)
+ * of the method. A given frame is {@literal null} if and only if the corresponding
+ * instruction cannot be reached (dead code).
+ * @throws AnalyzerException if a problem occurs during the analysis.
+ */
+ @SuppressWarnings("unchecked")
+ public Frame<V>[] analyze(final String owner, final MethodNode method) throws AnalyzerException {
+ if ((method.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
+ frames = (Frame<V>[]) new Frame<?>[0];
+ return frames;
+ }
+ insnList = method.instructions;
+ insnListSize = insnList.size();
+ handlers = (List<TryCatchBlockNode>[]) new List<?>[insnListSize];
+ frames = (Frame<V>[]) new Frame<?>[insnListSize];
+ subroutines = new Subroutine[insnListSize];
+ inInstructionsToProcess = new boolean[insnListSize];
+ instructionsToProcess = new int[insnListSize];
+ numInstructionsToProcess = 0;
+
+ // For each exception handler, and each instruction within its range, record in 'handlers' the
+ // fact that execution can flow from this instruction to the exception handler.
+ for (int i = 0; i < method.tryCatchBlocks.size(); ++i) {
+ TryCatchBlockNode tryCatchBlock = method.tryCatchBlocks.get(i);
+ int startIndex = insnList.indexOf(tryCatchBlock.start);
+ int endIndex = insnList.indexOf(tryCatchBlock.end);
+ for (int j = startIndex; j < endIndex; ++j) {
+ List<TryCatchBlockNode> insnHandlers = handlers[j];
+ if (insnHandlers == null) {
+ insnHandlers = new ArrayList<>();
+ handlers[j] = insnHandlers;
+ }
+ insnHandlers.add(tryCatchBlock);
+ }
+ }
+
+ // Finds the method's subroutines.
+ findSubroutines(method.maxLocals);
+
+ // Initializes the data structures for the control flow analysis.
+ Frame<V> currentFrame = computeInitialFrame(owner, method);
+ merge(0, currentFrame, null);
+ init(owner, method);
+
+ // Control flow analysis.
+ while (numInstructionsToProcess > 0) {
+ // Get and remove one instruction from the list of instructions to process.
+ int insnIndex = instructionsToProcess[--numInstructionsToProcess];
+ Frame<V> oldFrame = frames[insnIndex];
+ Subroutine subroutine = subroutines[insnIndex];
+ inInstructionsToProcess[insnIndex] = false;
+
+ // Simulate the execution of this instruction.
+ AbstractInsnNode insnNode = null;
+ try {
+ insnNode = method.instructions.get(insnIndex);
+ int insnOpcode = insnNode.getOpcode();
+ int insnType = insnNode.getType();
+
+ if (insnType == AbstractInsnNode.LABEL
+ || insnType == AbstractInsnNode.LINE
+ || insnType == AbstractInsnNode.FRAME) {
+ merge(insnIndex + 1, oldFrame, subroutine);
+ newControlFlowEdge(insnIndex, insnIndex + 1);
+ } else {
+ currentFrame.init(oldFrame).execute(insnNode, interpreter);
+ subroutine = subroutine == null ? null : new Subroutine(subroutine);
+
+ if (insnNode instanceof JumpInsnNode) {
+ JumpInsnNode jumpInsn = (JumpInsnNode) insnNode;
+ if (insnOpcode != GOTO && insnOpcode != JSR) {
+ currentFrame.initJumpTarget(insnOpcode, /* target = */ null);
+ merge(insnIndex + 1, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, insnIndex + 1);
+ }
+ int jumpInsnIndex = insnList.indexOf(jumpInsn.label);
+ currentFrame.initJumpTarget(insnOpcode, jumpInsn.label);
+ if (insnOpcode == JSR) {
+ merge(
+ jumpInsnIndex,
+ currentFrame,
+ new Subroutine(jumpInsn.label, method.maxLocals, jumpInsn));
+ } else {
+ merge(jumpInsnIndex, currentFrame, subroutine);
+ }
+ newControlFlowEdge(insnIndex, jumpInsnIndex);
+ } else if (insnNode instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) insnNode;
+ int targetInsnIndex = insnList.indexOf(lookupSwitchInsn.dflt);
+ currentFrame.initJumpTarget(insnOpcode, lookupSwitchInsn.dflt);
+ merge(targetInsnIndex, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, targetInsnIndex);
+ for (int i = 0; i < lookupSwitchInsn.labels.size(); ++i) {
+ LabelNode label = lookupSwitchInsn.labels.get(i);
+ targetInsnIndex = insnList.indexOf(label);
+ currentFrame.initJumpTarget(insnOpcode, label);
+ merge(targetInsnIndex, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, targetInsnIndex);
+ }
+ } else if (insnNode instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) insnNode;
+ int targetInsnIndex = insnList.indexOf(tableSwitchInsn.dflt);
+ currentFrame.initJumpTarget(insnOpcode, tableSwitchInsn.dflt);
+ merge(targetInsnIndex, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, targetInsnIndex);
+ for (int i = 0; i < tableSwitchInsn.labels.size(); ++i) {
+ LabelNode label = tableSwitchInsn.labels.get(i);
+ currentFrame.initJumpTarget(insnOpcode, label);
+ targetInsnIndex = insnList.indexOf(label);
+ merge(targetInsnIndex, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, targetInsnIndex);
+ }
+ } else if (insnOpcode == RET) {
+ if (subroutine == null) {
+ throw new AnalyzerException(insnNode, "RET instruction outside of a subroutine");
+ }
+ for (int i = 0; i < subroutine.callers.size(); ++i) {
+ JumpInsnNode caller = subroutine.callers.get(i);
+ int jsrInsnIndex = insnList.indexOf(caller);
+ if (frames[jsrInsnIndex] != null) {
+ merge(
+ jsrInsnIndex + 1,
+ frames[jsrInsnIndex],
+ currentFrame,
+ subroutines[jsrInsnIndex],
+ subroutine.localsUsed);
+ newControlFlowEdge(insnIndex, jsrInsnIndex + 1);
+ }
+ }
+ } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
+ if (subroutine != null) {
+ if (insnNode instanceof VarInsnNode) {
+ int varIndex = ((VarInsnNode) insnNode).var;
+ subroutine.localsUsed[varIndex] = true;
+ if (insnOpcode == LLOAD
+ || insnOpcode == DLOAD
+ || insnOpcode == LSTORE
+ || insnOpcode == DSTORE) {
+ subroutine.localsUsed[varIndex + 1] = true;
+ }
+ } else if (insnNode instanceof IincInsnNode) {
+ int varIndex = ((IincInsnNode) insnNode).var;
+ subroutine.localsUsed[varIndex] = true;
+ }
+ }
+ merge(insnIndex + 1, currentFrame, subroutine);
+ newControlFlowEdge(insnIndex, insnIndex + 1);
+ }
+ }
+
+ List<TryCatchBlockNode> insnHandlers = handlers[insnIndex];
+ if (insnHandlers != null) {
+ for (TryCatchBlockNode tryCatchBlock : insnHandlers) {
+ Type catchType;
+ if (tryCatchBlock.type == null) {
+ catchType = Type.getObjectType("java/lang/Throwable");
+ } else {
+ catchType = Type.getObjectType(tryCatchBlock.type);
+ }
+ if (newControlFlowExceptionEdge(insnIndex, tryCatchBlock)) {
+ Frame<V> handler = newFrame(oldFrame);
+ handler.clearStack();
+ handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType));
+ merge(insnList.indexOf(tryCatchBlock.handler), handler, subroutine);
+ }
+ }
+ }
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException(
+ e.node, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
+ } catch (RuntimeException e) {
+ // DontCheck(IllegalCatch): can't be fixed, for backward compatibility.
+ throw new AnalyzerException(
+ insnNode, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
+ }
+ }
+
+ return frames;
+ }
+
+ /**
+ * Analyzes the given method and computes and sets its maximum stack size and maximum number of
+ * local variables.
+ *
+ * @param owner the internal name of the class to which 'method' belongs (see {@link
+ * Type#getInternalName()}).
+ * @param method the method to be analyzed.
+ * @return the symbolic state of the execution stack frame at each bytecode instruction of the
+ * method. The size of the returned array is equal to the number of instructions (and labels)
+ * of the method. A given frame is {@literal null} if and only if the corresponding
+ * instruction cannot be reached (dead code).
+ * @throws AnalyzerException if a problem occurs during the analysis.
+ */
+ public Frame<V>[] analyzeAndComputeMaxs(final String owner, final MethodNode method)
+ throws AnalyzerException {
+ method.maxLocals = computeMaxLocals(method);
+ method.maxStack = -1;
+ analyze(owner, method);
+ method.maxStack = computeMaxStack(frames);
+ return frames;
+ }
+
+ /**
+ * Computes and returns the maximum number of local variables used in the given method.
+ *
+ * @param method a method.
+ * @return the maximum number of local variables used in the given method.
+ */
+ private static int computeMaxLocals(final MethodNode method) {
+ int maxLocals = Type.getArgumentsAndReturnSizes(method.desc) >> 2;
+ if ((method.access & Opcodes.ACC_STATIC) != 0) {
+ maxLocals -= 1;
+ }
+ for (AbstractInsnNode insnNode : method.instructions) {
+ if (insnNode instanceof VarInsnNode) {
+ int local = ((VarInsnNode) insnNode).var;
+ int size =
+ (insnNode.getOpcode() == Opcodes.LLOAD
+ || insnNode.getOpcode() == Opcodes.DLOAD
+ || insnNode.getOpcode() == Opcodes.LSTORE
+ || insnNode.getOpcode() == Opcodes.DSTORE)
+ ? 2
+ : 1;
+ maxLocals = Math.max(maxLocals, local + size);
+ } else if (insnNode instanceof IincInsnNode) {
+ int local = ((IincInsnNode) insnNode).var;
+ maxLocals = Math.max(maxLocals, local + 1);
+ }
+ }
+ return maxLocals;
+ }
+
+ /**
+ * Computes and returns the maximum stack size of a method, given its stack map frames.
+ *
+ * @param frames the stack map frames of a method.
+ * @return the maximum stack size of the given method.
+ */
+ private static int computeMaxStack(final Frame<?>[] frames) {
+ int maxStack = 0;
+ for (Frame<?> frame : frames) {
+ if (frame != null) {
+ int stackSize = 0;
+ for (int i = 0; i < frame.getStackSize(); ++i) {
+ stackSize += frame.getStack(i).getSize();
+ }
+ maxStack = Math.max(maxStack, stackSize);
+ }
+ }
+ return maxStack;
+ }
+
+ /**
+ * Finds the subroutines of the currently analyzed method and stores them in {@link #subroutines}.
+ *
+ * @param maxLocals the maximum number of local variables of the currently analyzed method (long
+ * and double values count for two variables).
+ * @throws AnalyzerException if the control flow graph can fall off the end of the code.
+ */
+ private void findSubroutines(final int maxLocals) throws AnalyzerException {
+ // For each instruction, compute the subroutine to which it belongs.
+ // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines.
+ Subroutine main = new Subroutine(null, maxLocals, null);
+ List<AbstractInsnNode> jsrInsns = new ArrayList<>();
+ findSubroutine(0, main, jsrInsns);
+ // Follow the nested subroutines, and collect their own nested subroutines, until all
+ // subroutines are found.
+ Map<LabelNode, Subroutine> jsrSubroutines = new HashMap<>();
+ while (!jsrInsns.isEmpty()) {
+ JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0);
+ Subroutine subroutine = jsrSubroutines.get(jsrInsn.label);
+ if (subroutine == null) {
+ subroutine = new Subroutine(jsrInsn.label, maxLocals, jsrInsn);
+ jsrSubroutines.put(jsrInsn.label, subroutine);
+ findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns);
+ } else {
+ subroutine.callers.add(jsrInsn);
+ }
+ }
+ // Clear the main 'subroutine', which is not a real subroutine (and was used only as an
+ // intermediate step above to find the real ones).
+ for (int i = 0; i < insnListSize; ++i) {
+ if (subroutines[i] != null && subroutines[i].start == null) {
+ subroutines[i] = null;
+ }
+ }
+ }
+
+ /**
+ * Follows the control flow graph of the currently analyzed method, starting at the given
+ * instruction index, and stores a copy of the given subroutine in {@link #subroutines} for each
+ * encountered instruction. Jumps to nested subroutines are <i>not</i> followed: instead, the
+ * corresponding instructions are put in the given list.
+ *
+ * @param insnIndex an instruction index.
+ * @param subroutine a subroutine.
+ * @param jsrInsns where the jsr instructions for nested subroutines must be put.
+ * @throws AnalyzerException if the control flow graph can fall off the end of the code.
+ */
+ private void findSubroutine(
+ final int insnIndex, final Subroutine subroutine, final List<AbstractInsnNode> jsrInsns)
+ throws AnalyzerException {
+ ArrayList<Integer> instructionIndicesToProcess = new ArrayList<>();
+ instructionIndicesToProcess.add(insnIndex);
+ while (!instructionIndicesToProcess.isEmpty()) {
+ int currentInsnIndex =
+ instructionIndicesToProcess.remove(instructionIndicesToProcess.size() - 1);
+ if (currentInsnIndex < 0 || currentInsnIndex >= insnListSize) {
+ throw new AnalyzerException(null, "Execution can fall off the end of the code");
+ }
+ if (subroutines[currentInsnIndex] != null) {
+ continue;
+ }
+ subroutines[currentInsnIndex] = new Subroutine(subroutine);
+ AbstractInsnNode currentInsn = insnList.get(currentInsnIndex);
+
+ // Push the normal successors of currentInsn onto instructionIndicesToProcess.
+ if (currentInsn instanceof JumpInsnNode) {
+ if (currentInsn.getOpcode() == JSR) {
+ // Do not follow a jsr, it leads to another subroutine!
+ jsrInsns.add(currentInsn);
+ } else {
+ JumpInsnNode jumpInsn = (JumpInsnNode) currentInsn;
+ instructionIndicesToProcess.add(insnList.indexOf(jumpInsn.label));
+ }
+ } else if (currentInsn instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) currentInsn;
+ findSubroutine(insnList.indexOf(tableSwitchInsn.dflt), subroutine, jsrInsns);
+ for (int i = tableSwitchInsn.labels.size() - 1; i >= 0; --i) {
+ LabelNode labelNode = tableSwitchInsn.labels.get(i);
+ instructionIndicesToProcess.add(insnList.indexOf(labelNode));
+ }
+ } else if (currentInsn instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) currentInsn;
+ findSubroutine(insnList.indexOf(lookupSwitchInsn.dflt), subroutine, jsrInsns);
+ for (int i = lookupSwitchInsn.labels.size() - 1; i >= 0; --i) {
+ LabelNode labelNode = lookupSwitchInsn.labels.get(i);
+ instructionIndicesToProcess.add(insnList.indexOf(labelNode));
+ }
+ }
+
+ // Push the exception handler successors of currentInsn onto instructionIndicesToProcess.
+ List<TryCatchBlockNode> insnHandlers = handlers[currentInsnIndex];
+ if (insnHandlers != null) {
+ for (TryCatchBlockNode tryCatchBlock : insnHandlers) {
+ instructionIndicesToProcess.add(insnList.indexOf(tryCatchBlock.handler));
+ }
+ }
+
+ // Push the next instruction, if the control flow can go from currentInsn to the next.
+ switch (currentInsn.getOpcode()) {
+ case GOTO:
+ case RET:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case RETURN:
+ case ATHROW:
+ break;
+ default:
+ instructionIndicesToProcess.add(currentInsnIndex + 1);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Computes the initial execution stack frame of the given method.
+ *
+ * @param owner the internal name of the class to which 'method' belongs (see {@link
+ * Type#getInternalName()}).
+ * @param method the method to be analyzed.
+ * @return the initial execution stack frame of the 'method'.
+ */
+ private Frame<V> computeInitialFrame(final String owner, final MethodNode method) {
+ Frame<V> frame = newFrame(method.maxLocals, method.maxStack);
+ int currentLocal = 0;
+ boolean isInstanceMethod = (method.access & ACC_STATIC) == 0;
+ if (isInstanceMethod) {
+ Type ownerType = Type.getObjectType(owner);
+ frame.setLocal(
+ currentLocal, interpreter.newParameterValue(isInstanceMethod, currentLocal, ownerType));
+ currentLocal++;
+ }
+ Type[] argumentTypes = Type.getArgumentTypes(method.desc);
+ for (Type argumentType : argumentTypes) {
+ frame.setLocal(
+ currentLocal,
+ interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentType));
+ currentLocal++;
+ if (argumentType.getSize() == 2) {
+ frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
+ currentLocal++;
+ }
+ }
+ while (currentLocal < method.maxLocals) {
+ frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
+ currentLocal++;
+ }
+ frame.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(method.desc)));
+ return frame;
+ }
+
+ /**
+ * Returns the symbolic execution stack frame for each instruction of the last analyzed method.
+ *
+ * @return the symbolic state of the execution stack frame at each bytecode instruction of the
+ * method. The size of the returned array is equal to the number of instructions (and labels)
+ * of the method. A given frame is {@literal null} if the corresponding instruction cannot be
+ * reached, or if an error occurred during the analysis of the method.
+ */
+ public Frame<V>[] getFrames() {
+ return frames;
+ }
+
+ /**
+ * Returns the exception handlers for the given instruction.
+ *
+ * @param insnIndex the index of an instruction of the last analyzed method.
+ * @return a list of {@link TryCatchBlockNode} objects.
+ */
+ public List<TryCatchBlockNode> getHandlers(final int insnIndex) {
+ return handlers[insnIndex];
+ }
+
+ /**
+ * Initializes this analyzer. This method is called just before the execution of control flow
+ * analysis loop in {@link #analyze}. The default implementation of this method does nothing.
+ *
+ * @param owner the internal name of the class to which the method belongs (see {@link
+ * Type#getInternalName()}).
+ * @param method the method to be analyzed.
+ * @throws AnalyzerException if a problem occurs.
+ */
+ protected void init(final String owner, final MethodNode method) throws AnalyzerException {
+ // Nothing to do.
+ }
+
+ /**
+ * Constructs a new frame with the given size.
+ *
+ * @param numLocals the maximum number of local variables of the frame.
+ * @param numStack the maximum stack size of the frame.
+ * @return the created frame.
+ */
+ protected Frame<V> newFrame(final int numLocals, final int numStack) {
+ return new Frame<>(numLocals, numStack);
+ }
+
+ /**
+ * Constructs a copy of the given frame.
+ *
+ * @param frame a frame.
+ * @return the created frame.
+ */
+ protected Frame<V> newFrame(final Frame<? extends V> frame) {
+ return new Frame<>(frame);
+ }
+
+ /**
+ * Creates a control flow graph edge. The default implementation of this method does nothing. It
+ * can be overridden in order to construct the control flow graph of a method (this method is
+ * called by the {@link #analyze} method during its visit of the method's code).
+ *
+ * @param insnIndex an instruction index.
+ * @param successorIndex index of a successor instruction.
+ */
+ protected void newControlFlowEdge(final int insnIndex, final int successorIndex) {
+ // Nothing to do.
+ }
+
+ /**
+ * Creates a control flow graph edge corresponding to an exception handler. The default
+ * implementation of this method does nothing. It can be overridden in order to construct the
+ * control flow graph of a method (this method is called by the {@link #analyze} method during its
+ * visit of the method's code).
+ *
+ * @param insnIndex an instruction index.
+ * @param successorIndex index of a successor instruction.
+ * @return true if this edge must be considered in the data flow analysis performed by this
+ * analyzer, or false otherwise. The default implementation of this method always returns
+ * true.
+ */
+ protected boolean newControlFlowExceptionEdge(final int insnIndex, final int successorIndex) {
+ return true;
+ }
+
+ /**
+ * Creates a control flow graph edge corresponding to an exception handler. The default
+ * implementation of this method delegates to {@link #newControlFlowExceptionEdge(int, int)}. It
+ * can be overridden in order to construct the control flow graph of a method (this method is
+ * called by the {@link #analyze} method during its visit of the method's code).
+ *
+ * @param insnIndex an instruction index.
+ * @param tryCatchBlock TryCatchBlockNode corresponding to this edge.
+ * @return true if this edge must be considered in the data flow analysis performed by this
+ * analyzer, or false otherwise. The default implementation of this method delegates to {@link
+ * #newControlFlowExceptionEdge(int, int)}.
+ */
+ protected boolean newControlFlowExceptionEdge(
+ final int insnIndex, final TryCatchBlockNode tryCatchBlock) {
+ return newControlFlowExceptionEdge(insnIndex, insnList.indexOf(tryCatchBlock.handler));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Merges the given frame and subroutine into the frame and subroutines at the given instruction
+ * index. If the frame or the subroutine at the given instruction index changes as a result of
+ * this merge, the instruction index is added to the list of instructions to process (if it is not
+ * already the case).
+ *
+ * @param insnIndex an instruction index.
+ * @param frame a frame. This frame is left unchanged by this method.
+ * @param subroutine a subroutine. This subroutine is left unchanged by this method.
+ * @throws AnalyzerException if the frames have incompatible sizes.
+ */
+ private void merge(final int insnIndex, final Frame<V> frame, final Subroutine subroutine)
+ throws AnalyzerException {
+ boolean changed;
+ Frame<V> oldFrame = frames[insnIndex];
+ if (oldFrame == null) {
+ frames[insnIndex] = newFrame(frame);
+ changed = true;
+ } else {
+ changed = oldFrame.merge(frame, interpreter);
+ }
+ Subroutine oldSubroutine = subroutines[insnIndex];
+ if (oldSubroutine == null) {
+ if (subroutine != null) {
+ subroutines[insnIndex] = new Subroutine(subroutine);
+ changed = true;
+ }
+ } else {
+ if (subroutine != null) {
+ changed |= oldSubroutine.merge(subroutine);
+ }
+ }
+ if (changed && !inInstructionsToProcess[insnIndex]) {
+ inInstructionsToProcess[insnIndex] = true;
+ instructionsToProcess[numInstructionsToProcess++] = insnIndex;
+ }
+ }
+
+ /**
+ * Merges the given frame and subroutine into the frame and subroutines at the given instruction
+ * index (case of a RET instruction). If the frame or the subroutine at the given instruction
+ * index changes as a result of this merge, the instruction index is added to the list of
+ * instructions to process (if it is not already the case).
+ *
+ * @param insnIndex the index of an instruction immediately following a jsr instruction.
+ * @param frameBeforeJsr the execution stack frame before the jsr instruction. This frame is
+ * merged into 'frameAfterRet'.
+ * @param frameAfterRet the execution stack frame after a ret instruction of the subroutine. This
+ * frame is merged into the frame at 'insnIndex' (after it has itself been merge with
+ * 'frameBeforeJsr').
+ * @param subroutineBeforeJsr if the jsr is itself part of a subroutine (case of nested
+ * subroutine), the subroutine it belongs to.
+ * @param localsUsed the local variables read or written in the subroutine.
+ * @throws AnalyzerException if the frames have incompatible sizes.
+ */
+ private void merge(
+ final int insnIndex,
+ final Frame<V> frameBeforeJsr,
+ final Frame<V> frameAfterRet,
+ final Subroutine subroutineBeforeJsr,
+ final boolean[] localsUsed)
+ throws AnalyzerException {
+ frameAfterRet.merge(frameBeforeJsr, localsUsed);
+
+ boolean changed;
+ Frame<V> oldFrame = frames[insnIndex];
+ if (oldFrame == null) {
+ frames[insnIndex] = newFrame(frameAfterRet);
+ changed = true;
+ } else {
+ changed = oldFrame.merge(frameAfterRet, interpreter);
+ }
+ Subroutine oldSubroutine = subroutines[insnIndex];
+ if (oldSubroutine != null && subroutineBeforeJsr != null) {
+ changed |= oldSubroutine.merge(subroutineBeforeJsr);
+ }
+ if (changed && !inInstructionsToProcess[insnIndex]) {
+ inInstructionsToProcess[insnIndex] = true;
+ instructionsToProcess[numInstructionsToProcess++] = insnIndex;
+ }
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/AnalyzerException.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/AnalyzerException.java
new file mode 100644
index 00000000..da3952b4
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/AnalyzerException.java
@@ -0,0 +1,89 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import org.objectweb.asm.tree.AbstractInsnNode;
+
+/**
+ * An exception thrown if a problem occurs during the analysis of a method.
+ *
+ * @author Bing Ran
+ * @author Eric Bruneton
+ */
+public class AnalyzerException extends Exception {
+
+ private static final long serialVersionUID = 3154190448018943333L;
+
+ /** The bytecode instruction where the analysis failed. */
+ public final transient AbstractInsnNode node;
+
+ /**
+ * Constructs a new {@link AnalyzerException}.
+ *
+ * @param insn the bytecode instruction where the analysis failed.
+ * @param message the reason why the analysis failed.
+ */
+ public AnalyzerException(final AbstractInsnNode insn, final String message) {
+ super(message);
+ this.node = insn;
+ }
+
+ /**
+ * Constructs a new {@link AnalyzerException}.
+ *
+ * @param insn the bytecode instruction where the analysis failed.
+ * @param message the reason why the analysis failed.
+ * @param cause the cause of the failure.
+ */
+ public AnalyzerException(
+ final AbstractInsnNode insn, final String message, final Throwable cause) {
+ super(message, cause);
+ this.node = insn;
+ }
+
+ /**
+ * Constructs a new {@link AnalyzerException}.
+ *
+ * @param insn the bytecode instruction where the analysis failed.
+ * @param message the reason why the analysis failed.
+ * @param expected an expected value.
+ * @param actual the actual value, different from the expected one.
+ */
+ public AnalyzerException(
+ final AbstractInsnNode insn,
+ final String message,
+ final Object expected,
+ final Value actual) {
+ super(
+ (message == null ? "Expected " : message + ": expected ")
+ + expected
+ + ", but found "
+ + actual);
+ this.node = insn;
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java
new file mode 100644
index 00000000..01972b6a
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java
@@ -0,0 +1,375 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MultiANewArrayInsnNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+
+/**
+ * An {@link Interpreter} for {@link BasicValue} values.
+ *
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes {
+
+ /**
+ * Special type used for the {@literal null} literal. This is an object reference type with
+ * descriptor 'Lnull;'.
+ */
+ public static final Type NULL_TYPE = Type.getObjectType("null");
+
+ /**
+ * Constructs a new {@link BasicInterpreter} for the latest ASM API version. <i>Subclasses must
+ * not use this constructor</i>. Instead, they must use the {@link #BasicInterpreter(int)}
+ * version.
+ */
+ public BasicInterpreter() {
+ super(/* latest api = */ ASM9);
+ if (getClass() != BasicInterpreter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link BasicInterpreter}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected BasicInterpreter(final int api) {
+ super(api);
+ }
+
+ @Override
+ public BasicValue newValue(final Type type) {
+ if (type == null) {
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+ switch (type.getSort()) {
+ case Type.VOID:
+ return null;
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ return BasicValue.INT_VALUE;
+ case Type.FLOAT:
+ return BasicValue.FLOAT_VALUE;
+ case Type.LONG:
+ return BasicValue.LONG_VALUE;
+ case Type.DOUBLE:
+ return BasicValue.DOUBLE_VALUE;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ return BasicValue.REFERENCE_VALUE;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public BasicValue newOperation(final AbstractInsnNode insn) throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case ACONST_NULL:
+ return newValue(NULL_TYPE);
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ return BasicValue.INT_VALUE;
+ case LCONST_0:
+ case LCONST_1:
+ return BasicValue.LONG_VALUE;
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ return BasicValue.FLOAT_VALUE;
+ case DCONST_0:
+ case DCONST_1:
+ return BasicValue.DOUBLE_VALUE;
+ case BIPUSH:
+ case SIPUSH:
+ return BasicValue.INT_VALUE;
+ case LDC:
+ Object value = ((LdcInsnNode) insn).cst;
+ if (value instanceof Integer) {
+ return BasicValue.INT_VALUE;
+ } else if (value instanceof Float) {
+ return BasicValue.FLOAT_VALUE;
+ } else if (value instanceof Long) {
+ return BasicValue.LONG_VALUE;
+ } else if (value instanceof Double) {
+ return BasicValue.DOUBLE_VALUE;
+ } else if (value instanceof String) {
+ return newValue(Type.getObjectType("java/lang/String"));
+ } else if (value instanceof Type) {
+ int sort = ((Type) value).getSort();
+ if (sort == Type.OBJECT || sort == Type.ARRAY) {
+ return newValue(Type.getObjectType("java/lang/Class"));
+ } else if (sort == Type.METHOD) {
+ return newValue(Type.getObjectType("java/lang/invoke/MethodType"));
+ } else {
+ throw new AnalyzerException(insn, "Illegal LDC value " + value);
+ }
+ } else if (value instanceof Handle) {
+ return newValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
+ } else if (value instanceof ConstantDynamic) {
+ return newValue(Type.getType(((ConstantDynamic) value).getDescriptor()));
+ } else {
+ throw new AnalyzerException(insn, "Illegal LDC value " + value);
+ }
+ case JSR:
+ return BasicValue.RETURNADDRESS_VALUE;
+ case GETSTATIC:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEW:
+ return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
+ throws AnalyzerException {
+ return value;
+ }
+
+ @Override
+ public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
+ throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case INEG:
+ case IINC:
+ case L2I:
+ case F2I:
+ case D2I:
+ case I2B:
+ case I2C:
+ case I2S:
+ return BasicValue.INT_VALUE;
+ case FNEG:
+ case I2F:
+ case L2F:
+ case D2F:
+ return BasicValue.FLOAT_VALUE;
+ case LNEG:
+ case I2L:
+ case F2L:
+ case D2L:
+ return BasicValue.LONG_VALUE;
+ case DNEG:
+ case I2D:
+ case L2D:
+ case F2D:
+ return BasicValue.DOUBLE_VALUE;
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case PUTSTATIC:
+ return null;
+ case GETFIELD:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEWARRAY:
+ switch (((IntInsnNode) insn).operand) {
+ case T_BOOLEAN:
+ return newValue(Type.getType("[Z"));
+ case T_CHAR:
+ return newValue(Type.getType("[C"));
+ case T_BYTE:
+ return newValue(Type.getType("[B"));
+ case T_SHORT:
+ return newValue(Type.getType("[S"));
+ case T_INT:
+ return newValue(Type.getType("[I"));
+ case T_FLOAT:
+ return newValue(Type.getType("[F"));
+ case T_DOUBLE:
+ return newValue(Type.getType("[D"));
+ case T_LONG:
+ return newValue(Type.getType("[J"));
+ default:
+ break;
+ }
+ throw new AnalyzerException(insn, "Invalid array type");
+ case ANEWARRAY:
+ return newValue(Type.getType("[" + Type.getObjectType(((TypeInsnNode) insn).desc)));
+ case ARRAYLENGTH:
+ return BasicValue.INT_VALUE;
+ case ATHROW:
+ return null;
+ case CHECKCAST:
+ return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
+ case INSTANCEOF:
+ return BasicValue.INT_VALUE;
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ return null;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public BasicValue binaryOperation(
+ final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2)
+ throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ return BasicValue.INT_VALUE;
+ case FALOAD:
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ return BasicValue.FLOAT_VALUE;
+ case LALOAD:
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ return BasicValue.LONG_VALUE;
+ case DALOAD:
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ return BasicValue.DOUBLE_VALUE;
+ case AALOAD:
+ return BasicValue.REFERENCE_VALUE;
+ case LCMP:
+ case FCMPL:
+ case FCMPG:
+ case DCMPL:
+ case DCMPG:
+ return BasicValue.INT_VALUE;
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case PUTFIELD:
+ return null;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public BasicValue ternaryOperation(
+ final AbstractInsnNode insn,
+ final BasicValue value1,
+ final BasicValue value2,
+ final BasicValue value3)
+ throws AnalyzerException {
+ return null;
+ }
+
+ @Override
+ public BasicValue naryOperation(
+ final AbstractInsnNode insn, final List<? extends BasicValue> values)
+ throws AnalyzerException {
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
+ } else if (opcode == INVOKEDYNAMIC) {
+ return newValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc));
+ } else {
+ return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
+ }
+ }
+
+ @Override
+ public void returnOperation(
+ final AbstractInsnNode insn, final BasicValue value, final BasicValue expected)
+ throws AnalyzerException {
+ // Nothing to do.
+ }
+
+ @Override
+ public BasicValue merge(final BasicValue value1, final BasicValue value2) {
+ if (!value1.equals(value2)) {
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+ return value1;
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java
new file mode 100644
index 00000000..3486a48e
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicValue.java
@@ -0,0 +1,129 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link Value} that is represented with its type in a seven types type system. This type system
+ * distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types.
+ *
+ * @author Eric Bruneton
+ */
+public class BasicValue implements Value {
+
+ /** An uninitialized value. */
+ public static final BasicValue UNINITIALIZED_VALUE = new BasicValue(null);
+
+ /** A byte, boolean, char, short, or int value. */
+ public static final BasicValue INT_VALUE = new BasicValue(Type.INT_TYPE);
+
+ /** A float value. */
+ public static final BasicValue FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE);
+
+ /** A long value. */
+ public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
+
+ /** A double value. */
+ public static final BasicValue DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE);
+
+ /** An object or array reference value. */
+ public static final BasicValue REFERENCE_VALUE =
+ new BasicValue(Type.getObjectType("java/lang/Object"));
+
+ /** A return address value (produced by a jsr instruction). */
+ public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(Type.VOID_TYPE);
+
+ /** The {@link Type} of this value, or {@literal null} for uninitialized values. */
+ private final Type type;
+
+ /**
+ * Constructs a new {@link BasicValue} of the given type.
+ *
+ * @param type the value type.
+ */
+ public BasicValue(final Type type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns the {@link Type} of this value.
+ *
+ * @return the {@link Type} of this value.
+ */
+ public Type getType() {
+ return type;
+ }
+
+ @Override
+ public int getSize() {
+ return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
+ }
+
+ /**
+ * Returns whether this value corresponds to an object or array reference.
+ *
+ * @return whether this value corresponds to an object or array reference.
+ */
+ public boolean isReference() {
+ return type != null && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY);
+ }
+
+ @Override
+ public boolean equals(final Object value) {
+ if (value == this) {
+ return true;
+ } else if (value instanceof BasicValue) {
+ if (type == null) {
+ return ((BasicValue) value).type == null;
+ } else {
+ return type.equals(((BasicValue) value).type);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return type == null ? 0 : type.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ if (this == UNINITIALIZED_VALUE) {
+ return ".";
+ } else if (this == RETURNADDRESS_VALUE) {
+ return "A";
+ } else if (this == REFERENCE_VALUE) {
+ return "R";
+ } else {
+ return type.getDescriptor();
+ }
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java
new file mode 100644
index 00000000..07aff3e6
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java
@@ -0,0 +1,450 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/**
+ * An extended {@link BasicInterpreter} that checks that bytecode instructions are correctly used.
+ *
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class BasicVerifier extends BasicInterpreter {
+
+ /**
+ * Constructs a new {@link BasicVerifier} for the latest ASM API version. <i>Subclasses must not
+ * use this constructor</i>. Instead, they must use the {@link #BasicVerifier(int)} version.
+ */
+ public BasicVerifier() {
+ super(/* latest api = */ ASM9);
+ if (getClass() != BasicVerifier.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link BasicVerifier}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected BasicVerifier(final int api) {
+ super(api);
+ }
+
+ @Override
+ public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
+ throws AnalyzerException {
+ Value expected;
+ switch (insn.getOpcode()) {
+ case ILOAD:
+ case ISTORE:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FLOAD:
+ case FSTORE:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LLOAD:
+ case LSTORE:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DLOAD:
+ case DSTORE:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case ALOAD:
+ if (!value.isReference()) {
+ throw new AnalyzerException(insn, null, "an object reference", value);
+ }
+ return value;
+ case ASTORE:
+ if (!value.isReference() && !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
+ throw new AnalyzerException(insn, null, "an object reference or a return address", value);
+ }
+ return value;
+ default:
+ return value;
+ }
+ if (!expected.equals(value)) {
+ throw new AnalyzerException(insn, null, expected, value);
+ }
+ return value;
+ }
+
+ @Override
+ public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
+ throws AnalyzerException {
+ BasicValue expected;
+ switch (insn.getOpcode()) {
+ case INEG:
+ case IINC:
+ case I2F:
+ case I2L:
+ case I2D:
+ case I2B:
+ case I2C:
+ case I2S:
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case NEWARRAY:
+ case ANEWARRAY:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FNEG:
+ case F2I:
+ case F2L:
+ case F2D:
+ case FRETURN:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LNEG:
+ case L2I:
+ case L2F:
+ case L2D:
+ case LRETURN:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DNEG:
+ case D2I:
+ case D2F:
+ case D2L:
+ case DRETURN:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case GETFIELD:
+ expected = newValue(Type.getObjectType(((FieldInsnNode) insn).owner));
+ break;
+ case ARRAYLENGTH:
+ if (!isArrayValue(value)) {
+ throw new AnalyzerException(insn, null, "an array reference", value);
+ }
+ return super.unaryOperation(insn, value);
+ case CHECKCAST:
+ case ARETURN:
+ case ATHROW:
+ case INSTANCEOF:
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ if (!value.isReference()) {
+ throw new AnalyzerException(insn, null, "an object reference", value);
+ }
+ return super.unaryOperation(insn, value);
+ case PUTSTATIC:
+ expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
+ break;
+ default:
+ throw new AssertionError();
+ }
+ if (!isSubTypeOf(value, expected)) {
+ throw new AnalyzerException(insn, null, expected, value);
+ }
+ return super.unaryOperation(insn, value);
+ }
+
+ @Override
+ public BasicValue binaryOperation(
+ final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2)
+ throws AnalyzerException {
+ BasicValue expected1;
+ BasicValue expected2;
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ expected1 = newValue(Type.getType("[I"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case BALOAD:
+ if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[Z"));
+ } else {
+ expected1 = newValue(Type.getType("[B"));
+ }
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case CALOAD:
+ expected1 = newValue(Type.getType("[C"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case SALOAD:
+ expected1 = newValue(Type.getType("[S"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case LALOAD:
+ expected1 = newValue(Type.getType("[J"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FALOAD:
+ expected1 = newValue(Type.getType("[F"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DALOAD:
+ expected1 = newValue(Type.getType("[D"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case AALOAD:
+ expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ expected1 = BasicValue.INT_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ case FCMPL:
+ case FCMPG:
+ expected1 = BasicValue.FLOAT_VALUE;
+ expected2 = BasicValue.FLOAT_VALUE;
+ break;
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LAND:
+ case LOR:
+ case LXOR:
+ case LCMP:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.LONG_VALUE;
+ break;
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ case DCMPL:
+ case DCMPG:
+ expected1 = BasicValue.DOUBLE_VALUE;
+ expected2 = BasicValue.DOUBLE_VALUE;
+ break;
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ expected1 = BasicValue.REFERENCE_VALUE;
+ expected2 = BasicValue.REFERENCE_VALUE;
+ break;
+ case PUTFIELD:
+ FieldInsnNode fieldInsn = (FieldInsnNode) insn;
+ expected1 = newValue(Type.getObjectType(fieldInsn.owner));
+ expected2 = newValue(Type.getType(fieldInsn.desc));
+ break;
+ default:
+ throw new AssertionError();
+ }
+ if (!isSubTypeOf(value1, expected1)) {
+ throw new AnalyzerException(insn, "First argument", expected1, value1);
+ } else if (!isSubTypeOf(value2, expected2)) {
+ throw new AnalyzerException(insn, "Second argument", expected2, value2);
+ }
+ if (insn.getOpcode() == AALOAD) {
+ return getElementValue(value1);
+ } else {
+ return super.binaryOperation(insn, value1, value2);
+ }
+ }
+
+ @Override
+ public BasicValue ternaryOperation(
+ final AbstractInsnNode insn,
+ final BasicValue value1,
+ final BasicValue value2,
+ final BasicValue value3)
+ throws AnalyzerException {
+ BasicValue expected1;
+ BasicValue expected3;
+ switch (insn.getOpcode()) {
+ case IASTORE:
+ expected1 = newValue(Type.getType("[I"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case BASTORE:
+ if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[Z"));
+ } else {
+ expected1 = newValue(Type.getType("[B"));
+ }
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case CASTORE:
+ expected1 = newValue(Type.getType("[C"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case SASTORE:
+ expected1 = newValue(Type.getType("[S"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case LASTORE:
+ expected1 = newValue(Type.getType("[J"));
+ expected3 = BasicValue.LONG_VALUE;
+ break;
+ case FASTORE:
+ expected1 = newValue(Type.getType("[F"));
+ expected3 = BasicValue.FLOAT_VALUE;
+ break;
+ case DASTORE:
+ expected1 = newValue(Type.getType("[D"));
+ expected3 = BasicValue.DOUBLE_VALUE;
+ break;
+ case AASTORE:
+ expected1 = value1;
+ expected3 = BasicValue.REFERENCE_VALUE;
+ break;
+ default:
+ throw new AssertionError();
+ }
+ if (!isSubTypeOf(value1, expected1)) {
+ throw new AnalyzerException(
+ insn, "First argument", "a " + expected1 + " array reference", value1);
+ } else if (!BasicValue.INT_VALUE.equals(value2)) {
+ throw new AnalyzerException(insn, "Second argument", BasicValue.INT_VALUE, value2);
+ } else if (!isSubTypeOf(value3, expected3)) {
+ throw new AnalyzerException(insn, "Third argument", expected3, value3);
+ }
+ return null;
+ }
+
+ @Override
+ public BasicValue naryOperation(
+ final AbstractInsnNode insn, final List<? extends BasicValue> values)
+ throws AnalyzerException {
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ for (BasicValue value : values) {
+ if (!BasicValue.INT_VALUE.equals(value)) {
+ throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, value);
+ }
+ }
+ } else {
+ int i = 0;
+ int j = 0;
+ if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
+ Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
+ if (!isSubTypeOf(values.get(i++), newValue(owner))) {
+ throw new AnalyzerException(insn, "Method owner", newValue(owner), values.get(0));
+ }
+ }
+ String methodDescriptor =
+ (opcode == INVOKEDYNAMIC)
+ ? ((InvokeDynamicInsnNode) insn).desc
+ : ((MethodInsnNode) insn).desc;
+ Type[] args = Type.getArgumentTypes(methodDescriptor);
+ while (i < values.size()) {
+ BasicValue expected = newValue(args[j++]);
+ BasicValue actual = values.get(i++);
+ if (!isSubTypeOf(actual, expected)) {
+ throw new AnalyzerException(insn, "Argument " + j, expected, actual);
+ }
+ }
+ }
+ return super.naryOperation(insn, values);
+ }
+
+ @Override
+ public void returnOperation(
+ final AbstractInsnNode insn, final BasicValue value, final BasicValue expected)
+ throws AnalyzerException {
+ if (!isSubTypeOf(value, expected)) {
+ throw new AnalyzerException(insn, "Incompatible return type", expected, value);
+ }
+ }
+
+ /**
+ * Returns whether the given value corresponds to an array reference.
+ *
+ * @param value a value.
+ * @return whether 'value' corresponds to an array reference.
+ */
+ protected boolean isArrayValue(final BasicValue value) {
+ return value.isReference();
+ }
+
+ /**
+ * Returns the value corresponding to the type of the elements of the given array reference value.
+ *
+ * @param objectArrayValue a value corresponding to array of object (or array) references.
+ * @return the value corresponding to the type of the elements of 'objectArrayValue'.
+ * @throws AnalyzerException if objectArrayValue does not correspond to an array type.
+ */
+ protected BasicValue getElementValue(final BasicValue objectArrayValue) throws AnalyzerException {
+ return BasicValue.REFERENCE_VALUE;
+ }
+
+ /**
+ * Returns whether the type corresponding to the first argument is a subtype of the type
+ * corresponding to the second argument.
+ *
+ * @param value a value.
+ * @param expected another value.
+ * @return whether the type corresponding to 'value' is a subtype of the type corresponding to
+ * 'expected'.
+ */
+ protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+ return value.equals(expected);
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java
new file mode 100644
index 00000000..2776fb30
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java
@@ -0,0 +1,752 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.IincInsnNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MultiANewArrayInsnNode;
+import org.objectweb.asm.tree.VarInsnNode;
+
+/**
+ * A symbolic execution stack frame. A stack frame contains a set of local variable slots, and an
+ * operand stack. Warning: long and double values are represented with <i>two</i> slots in local
+ * variables, and with <i>one</i> slot in the operand stack.
+ *
+ * @param <V> type of the Value used for the analysis.
+ * @author Eric Bruneton
+ */
+public class Frame<V extends Value> {
+
+ /** The maximum size of the operand stack of any method. */
+ private static final int MAX_STACK_SIZE = 65536;
+
+ /**
+ * The expected return type of the analyzed method, or {@literal null} if the method returns void.
+ */
+ private V returnValue;
+
+ /**
+ * The local variables and the operand stack of this frame. The first {@link #numLocals} elements
+ * correspond to the local variables. The following {@link #numStack} elements correspond to the
+ * operand stack. Long and double values are represented with two elements in the local variables
+ * section, and with one element in the operand stack section.
+ */
+ private V[] values;
+
+ /**
+ * The number of local variables of this frame. Long and double values are represented with two
+ * elements.
+ */
+ private int numLocals;
+
+ /**
+ * The number of elements in the operand stack. Long and double values are represented with a
+ * single element.
+ */
+ private int numStack;
+
+ /**
+ * The maximum number of elements in the operand stack. Long and double values are represented
+ * with a single element.
+ */
+ private int maxStack;
+
+ /**
+ * Constructs a new frame with the given size.
+ *
+ * @param numLocals the number of local variables of the frame. Long and double values are
+ * represented with two elements.
+ * @param maxStack the maximum number of elements in the operand stack, or -1 if there is no
+ * maximum value. Long and double values are represented with a single element.
+ */
+ @SuppressWarnings("unchecked")
+ public Frame(final int numLocals, final int maxStack) {
+ this.values = (V[]) new Value[numLocals + (maxStack >= 0 ? maxStack : 4)];
+ this.numLocals = numLocals;
+ this.numStack = 0;
+ this.maxStack = maxStack >= 0 ? maxStack : MAX_STACK_SIZE;
+ }
+
+ /**
+ * Constructs a copy of the given Frame.
+ *
+ * @param frame a frame.
+ */
+ public Frame(final Frame<? extends V> frame) {
+ this(frame.numLocals, frame.values.length - frame.numLocals);
+ init(frame); // NOPMD(ConstructorCallsOverridableMethod): can't fix for backward compatibility.
+ }
+
+ /**
+ * Copies the state of the given frame into this frame.
+ *
+ * @param frame a frame.
+ * @return this frame.
+ */
+ public Frame<V> init(final Frame<? extends V> frame) {
+ returnValue = frame.returnValue;
+ if (values.length < frame.values.length) {
+ values = frame.values.clone();
+ } else {
+ System.arraycopy(frame.values, 0, values, 0, frame.values.length);
+ }
+ numLocals = frame.numLocals;
+ numStack = frame.numStack;
+ maxStack = frame.maxStack;
+ return this;
+ }
+
+ /**
+ * Initializes a frame corresponding to the target or to the successor of a jump instruction. This
+ * method is called by {@link Analyzer#analyze(String, org.objectweb.asm.tree.MethodNode)} while
+ * interpreting jump instructions. It is called once for each possible target of the jump
+ * instruction, and once for its successor instruction (except for GOTO and JSR), before the frame
+ * is merged with the existing frame at this location. The default implementation of this method
+ * does nothing.
+ *
+ * <p>Overriding this method and changing the frame values allows implementing branch-sensitive
+ * analyses.
+ *
+ * @param opcode the opcode of the jump instruction. Can be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
+ * IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE,
+ * GOTO, JSR, IFNULL, IFNONNULL, TABLESWITCH or LOOKUPSWITCH.
+ * @param target a target of the jump instruction this frame corresponds to, or {@literal null} if
+ * this frame corresponds to the successor of the jump instruction (i.e. the next instruction
+ * in the instructions sequence).
+ */
+ public void initJumpTarget(final int opcode, final LabelNode target) {
+ // Does nothing by default.
+ }
+
+ /**
+ * Sets the expected return type of the analyzed method.
+ *
+ * @param v the expected return type of the analyzed method, or {@literal null} if the method
+ * returns void.
+ */
+ public void setReturn(final V v) {
+ returnValue = v;
+ }
+
+ /**
+ * Returns the maximum number of local variables of this frame. Long and double values are
+ * represented with two variables.
+ *
+ * @return the maximum number of local variables of this frame.
+ */
+ public int getLocals() {
+ return numLocals;
+ }
+
+ /**
+ * Returns the maximum number of elements in the operand stack of this frame. Long and double
+ * values are represented with a single element.
+ *
+ * @return the maximum number of elements in the operand stack of this frame.
+ */
+ public int getMaxStackSize() {
+ return maxStack;
+ }
+
+ /**
+ * Returns the value of the given local variable. Long and double values are represented with two
+ * variables.
+ *
+ * @param index a local variable index.
+ * @return the value of the given local variable.
+ * @throws IndexOutOfBoundsException if the variable does not exist.
+ */
+ public V getLocal(final int index) {
+ if (index >= numLocals) {
+ throw new IndexOutOfBoundsException("Trying to get an inexistant local variable " + index);
+ }
+ return values[index];
+ }
+
+ /**
+ * Sets the value of the given local variable. Long and double values are represented with two
+ * variables.
+ *
+ * @param index a local variable index.
+ * @param value the new value of this local variable.
+ * @throws IndexOutOfBoundsException if the variable does not exist.
+ */
+ public void setLocal(final int index, final V value) {
+ if (index >= numLocals) {
+ throw new IndexOutOfBoundsException("Trying to set an inexistant local variable " + index);
+ }
+ values[index] = value;
+ }
+
+ /**
+ * Returns the number of elements in the operand stack of this frame. Long and double values are
+ * represented with a single element.
+ *
+ * @return the number of elements in the operand stack of this frame.
+ */
+ public int getStackSize() {
+ return numStack;
+ }
+
+ /**
+ * Returns the value of the given operand stack slot.
+ *
+ * @param index the index of an operand stack slot.
+ * @return the value of the given operand stack slot.
+ * @throws IndexOutOfBoundsException if the operand stack slot does not exist.
+ */
+ public V getStack(final int index) {
+ return values[numLocals + index];
+ }
+
+ /**
+ * Sets the value of the given stack slot.
+ *
+ * @param index the index of an operand stack slot.
+ * @param value the new value of the stack slot.
+ * @throws IndexOutOfBoundsException if the stack slot does not exist.
+ */
+ public void setStack(final int index, final V value) {
+ values[numLocals + index] = value;
+ }
+
+ /** Clears the operand stack of this frame. */
+ public void clearStack() {
+ numStack = 0;
+ }
+
+ /**
+ * Pops a value from the operand stack of this frame.
+ *
+ * @return the value that has been popped from the stack.
+ * @throws IndexOutOfBoundsException if the operand stack is empty.
+ */
+ public V pop() {
+ if (numStack == 0) {
+ throw new IndexOutOfBoundsException("Cannot pop operand off an empty stack.");
+ }
+ return values[numLocals + (--numStack)];
+ }
+
+ /**
+ * Pushes a value into the operand stack of this frame.
+ *
+ * @param value the value that must be pushed into the stack.
+ * @throws IndexOutOfBoundsException if the operand stack is full.
+ */
+ @SuppressWarnings("unchecked")
+ public void push(final V value) {
+ if (numLocals + numStack >= values.length) {
+ if (numLocals + numStack >= maxStack) {
+ throw new IndexOutOfBoundsException("Insufficient maximum stack size.");
+ }
+ V[] oldValues = values;
+ values = (V[]) new Value[2 * values.length];
+ System.arraycopy(oldValues, 0, values, 0, oldValues.length);
+ }
+ values[numLocals + (numStack++)] = value;
+ }
+
+ /**
+ * Simulates the execution of the given instruction on this execution stack frame.
+ *
+ * @param insn the instruction to execute.
+ * @param interpreter the interpreter to use to compute values from other values.
+ * @throws AnalyzerException if the instruction cannot be executed on this execution frame (e.g. a
+ * POP on an empty operand stack).
+ */
+ public void execute(final AbstractInsnNode insn, final Interpreter<V> interpreter)
+ throws AnalyzerException {
+ V value1;
+ V value2;
+ V value3;
+ V value4;
+ int varIndex;
+
+ switch (insn.getOpcode()) {
+ case Opcodes.NOP:
+ break;
+ case Opcodes.ACONST_NULL:
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ case Opcodes.LDC:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.ILOAD:
+ case Opcodes.LLOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.DLOAD:
+ case Opcodes.ALOAD:
+ push(interpreter.copyOperation(insn, getLocal(((VarInsnNode) insn).var)));
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.LSTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.DSTORE:
+ case Opcodes.ASTORE:
+ value1 = interpreter.copyOperation(insn, pop());
+ varIndex = ((VarInsnNode) insn).var;
+ setLocal(varIndex, value1);
+ if (value1.getSize() == 2) {
+ setLocal(varIndex + 1, interpreter.newEmptyValue(varIndex + 1));
+ }
+ if (varIndex > 0) {
+ Value local = getLocal(varIndex - 1);
+ if (local != null && local.getSize() == 2) {
+ setLocal(varIndex - 1, interpreter.newEmptyValue(varIndex - 1));
+ }
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.LASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.DASTORE:
+ case Opcodes.AASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ value3 = pop();
+ value2 = pop();
+ value1 = pop();
+ interpreter.ternaryOperation(insn, value1, value2, value3);
+ break;
+ case Opcodes.POP:
+ if (pop().getSize() == 2) {
+ throw new AnalyzerException(insn, "Illegal use of POP");
+ }
+ break;
+ case Opcodes.POP2:
+ if (pop().getSize() == 1 && pop().getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of POP2");
+ }
+ break;
+ case Opcodes.DUP:
+ value1 = pop();
+ if (value1.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of DUP");
+ }
+ push(value1);
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ case Opcodes.DUP_X1:
+ value1 = pop();
+ value2 = pop();
+ if (value1.getSize() != 1 || value2.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of DUP_X1");
+ }
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP_X2:
+ value1 = pop();
+ if (value1.getSize() == 1 && executeDupX2(insn, value1, interpreter)) {
+ break;
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP_X2");
+ case Opcodes.DUP2:
+ value1 = pop();
+ if (value1.getSize() == 1) {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ push(value2);
+ push(value1);
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ }
+ } else {
+ push(value1);
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP2");
+ case Opcodes.DUP2_X1:
+ value1 = pop();
+ if (value1.getSize() == 1) {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ }
+ }
+ } else {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ break;
+ }
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
+ case Opcodes.DUP2_X2:
+ value1 = pop();
+ if (value1.getSize() == 1) {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
+ value4 = pop();
+ if (value4.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ push(value4);
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ }
+ } else {
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ }
+ }
+ } else if (executeDupX2(insn, value1, interpreter)) {
+ break;
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
+ case Opcodes.SWAP:
+ value2 = pop();
+ value1 = pop();
+ if (value1.getSize() != 1 || value2.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of SWAP");
+ }
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.LALOAD:
+ case Opcodes.FALOAD:
+ case Opcodes.DALOAD:
+ case Opcodes.AALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IADD:
+ case Opcodes.LADD:
+ case Opcodes.FADD:
+ case Opcodes.DADD:
+ case Opcodes.ISUB:
+ case Opcodes.LSUB:
+ case Opcodes.FSUB:
+ case Opcodes.DSUB:
+ case Opcodes.IMUL:
+ case Opcodes.LMUL:
+ case Opcodes.FMUL:
+ case Opcodes.DMUL:
+ case Opcodes.IDIV:
+ case Opcodes.LDIV:
+ case Opcodes.FDIV:
+ case Opcodes.DDIV:
+ case Opcodes.IREM:
+ case Opcodes.LREM:
+ case Opcodes.FREM:
+ case Opcodes.DREM:
+ case Opcodes.ISHL:
+ case Opcodes.LSHL:
+ case Opcodes.ISHR:
+ case Opcodes.LSHR:
+ case Opcodes.IUSHR:
+ case Opcodes.LUSHR:
+ case Opcodes.IAND:
+ case Opcodes.LAND:
+ case Opcodes.IOR:
+ case Opcodes.LOR:
+ case Opcodes.IXOR:
+ case Opcodes.LXOR:
+ case Opcodes.LCMP:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ value2 = pop();
+ value1 = pop();
+ push(interpreter.binaryOperation(insn, value1, value2));
+ break;
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.IINC:
+ varIndex = ((IincInsnNode) insn).var;
+ setLocal(varIndex, interpreter.unaryOperation(insn, getLocal(varIndex)));
+ break;
+ case Opcodes.I2L:
+ case Opcodes.I2F:
+ case Opcodes.I2D:
+ case Opcodes.L2I:
+ case Opcodes.L2F:
+ case Opcodes.L2D:
+ case Opcodes.F2I:
+ case Opcodes.F2L:
+ case Opcodes.F2D:
+ case Opcodes.D2I:
+ case Opcodes.D2L:
+ case Opcodes.D2F:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.PUTFIELD:
+ value2 = pop();
+ value1 = pop();
+ interpreter.binaryOperation(insn, value1, value2);
+ break;
+ case Opcodes.GOTO:
+ break;
+ case Opcodes.JSR:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.RET:
+ break;
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ value1 = pop();
+ interpreter.unaryOperation(insn, value1);
+ interpreter.returnOperation(insn, value1, returnValue);
+ break;
+ case Opcodes.RETURN:
+ if (returnValue != null) {
+ throw new AnalyzerException(insn, "Incompatible return type");
+ }
+ break;
+ case Opcodes.GETSTATIC:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.PUTSTATIC:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.GETFIELD:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE:
+ executeInvokeInsn(insn, ((MethodInsnNode) insn).desc, interpreter);
+ break;
+ case Opcodes.INVOKEDYNAMIC:
+ executeInvokeInsn(insn, ((InvokeDynamicInsnNode) insn).desc, interpreter);
+ break;
+ case Opcodes.NEW:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.NEWARRAY:
+ case Opcodes.ANEWARRAY:
+ case Opcodes.ARRAYLENGTH:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.ATHROW:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.CHECKCAST:
+ case Opcodes.INSTANCEOF:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ List<V> valueList = new ArrayList<>();
+ for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
+ valueList.add(0, pop());
+ }
+ push(interpreter.naryOperation(insn, valueList));
+ break;
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ default:
+ throw new AnalyzerException(insn, "Illegal opcode " + insn.getOpcode());
+ }
+ }
+
+ private boolean executeDupX2(
+ final AbstractInsnNode insn, final V value1, final Interpreter<V> interpreter)
+ throws AnalyzerException {
+ V value2 = pop();
+ if (value2.getSize() == 1) {
+ V value3 = pop();
+ if (value3.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value1));
+ push(value3);
+ push(value2);
+ push(value1);
+ return true;
+ }
+ } else {
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ return true;
+ }
+ return false;
+ }
+
+ private void executeInvokeInsn(
+ final AbstractInsnNode insn, final String methodDescriptor, final Interpreter<V> interpreter)
+ throws AnalyzerException {
+ ArrayList<V> valueList = new ArrayList<>();
+ for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) {
+ valueList.add(0, pop());
+ }
+ if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) {
+ valueList.add(0, pop());
+ }
+ if (Type.getReturnType(methodDescriptor) == Type.VOID_TYPE) {
+ interpreter.naryOperation(insn, valueList);
+ } else {
+ push(interpreter.naryOperation(insn, valueList));
+ }
+ }
+
+ /**
+ * Merges the given frame into this frame.
+ *
+ * @param frame a frame. This frame is left unchanged by this method.
+ * @param interpreter the interpreter used to merge values.
+ * @return {@literal true} if this frame has been changed as a result of the merge operation, or
+ * {@literal false} otherwise.
+ * @throws AnalyzerException if the frames have incompatible sizes.
+ */
+ public boolean merge(final Frame<? extends V> frame, final Interpreter<V> interpreter)
+ throws AnalyzerException {
+ if (numStack != frame.numStack) {
+ throw new AnalyzerException(null, "Incompatible stack heights");
+ }
+ boolean changed = false;
+ for (int i = 0; i < numLocals + numStack; ++i) {
+ V v = interpreter.merge(values[i], frame.values[i]);
+ if (!v.equals(values[i])) {
+ values[i] = v;
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ /**
+ * Merges the given frame into this frame (case of a subroutine). The operand stacks are not
+ * merged, and only the local variables that have not been used by the subroutine are merged.
+ *
+ * @param frame a frame. This frame is left unchanged by this method.
+ * @param localsUsed the local variables that are read or written by the subroutine. The i-th
+ * element is true if and only if the local variable at index i is read or written by the
+ * subroutine.
+ * @return {@literal true} if this frame has been changed as a result of the merge operation, or
+ * {@literal false} otherwise.
+ */
+ public boolean merge(final Frame<? extends V> frame, final boolean[] localsUsed) {
+ boolean changed = false;
+ for (int i = 0; i < numLocals; ++i) {
+ if (!localsUsed[i] && !values[i].equals(frame.values[i])) {
+ values[i] = frame.values[i];
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ /**
+ * Returns a string representation of this frame.
+ *
+ * @return a string representation of this frame.
+ */
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < getLocals(); ++i) {
+ stringBuilder.append(getLocal(i));
+ }
+ stringBuilder.append(' ');
+ for (int i = 0; i < getStackSize(); ++i) {
+ stringBuilder.append(getStack(i).toString());
+ }
+ return stringBuilder.toString();
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Interpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Interpreter.java
new file mode 100644
index 00000000..ddcda09b
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Interpreter.java
@@ -0,0 +1,267 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+
+/**
+ * A semantic bytecode interpreter. More precisely, this interpreter only manages the computation of
+ * values from other values: it does not manage the transfer of values to or from the stack, and to
+ * or from the local variables. This separation allows a generic bytecode {@link Analyzer} to work
+ * with various semantic interpreters, without needing to duplicate the code to simulate the
+ * transfer of values.
+ *
+ * @param <V> type of the Value used for the analysis.
+ * @author Eric Bruneton
+ */
+public abstract class Interpreter<V extends Value> {
+
+ /**
+ * The ASM API version supported by this interpreter. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /**
+ * Constructs a new {@link Interpreter}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected Interpreter(final int api) {
+ this.api = api;
+ }
+
+ /**
+ * Creates a new value that represents the given type.
+ *
+ * <p>Called for method parameters (including <code>this</code>), exception handler variable and
+ * with <code>null</code> type for variables reserved by long and double types.
+ *
+ * <p>An interpreter may choose to implement one or more of {@link
+ * Interpreter#newReturnTypeValue(Type)}, {@link Interpreter#newParameterValue(boolean, int,
+ * Type)}, {@link Interpreter#newEmptyValue(int)}, {@link
+ * Interpreter#newExceptionValue(TryCatchBlockNode, Frame, Type)} to distinguish different types
+ * of new value.
+ *
+ * @param type a primitive or reference type, or {@literal null} to represent an uninitialized
+ * value.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public abstract V newValue(Type type);
+
+ /**
+ * Creates a new value that represents the given parameter type. This method is called to
+ * initialize the value of a local corresponding to a method parameter in a frame.
+ *
+ * <p>By default, calls <code>newValue(type)</code>.
+ *
+ * @param isInstanceMethod {@literal true} if the method is non-static.
+ * @param local the local variable index.
+ * @param type a primitive or reference type.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public V newParameterValue(final boolean isInstanceMethod, final int local, final Type type) {
+ return newValue(type);
+ }
+
+ /**
+ * Creates a new value that represents the given return type. This method is called to initialize
+ * the return type value of a frame.
+ *
+ * <p>By default, calls <code>newValue(type)</code>.
+ *
+ * @param type a primitive or reference type.
+ * @return a value that represents the given type. The size of the returned value must be equal to
+ * the size of the given type.
+ */
+ public V newReturnTypeValue(final Type type) {
+ return newValue(type);
+ }
+
+ /**
+ * Creates a new uninitialized value for a local variable. This method is called to initialize the
+ * value of a local that does not correspond to a method parameter, and to reset one half of a
+ * size-2 value when the other half is assigned a size-1 value.
+ *
+ * <p>By default, calls <code>newValue(null)</code>.
+ *
+ * @param local the local variable index.
+ * @return a value representing an uninitialized value. The size of the returned value must be
+ * equal to 1.
+ */
+ public V newEmptyValue(final int local) {
+ return newValue(null);
+ }
+
+ /**
+ * Creates a new value that represents the given exception type. This method is called to
+ * initialize the exception value on the call stack at the entry of an exception handler.
+ *
+ * <p>By default, calls <code>newValue(exceptionType)</code>.
+ *
+ * @param tryCatchBlockNode the exception handler.
+ * @param handlerFrame the exception handler frame.
+ * @param exceptionType the exception type handled by this handler.
+ * @return a value that represents the given {@code exceptionType}. The size of the returned value
+ * must be equal to 1.
+ */
+ public V newExceptionValue(
+ final TryCatchBlockNode tryCatchBlockNode,
+ final Frame<V> handlerFrame,
+ final Type exceptionType) {
+ return newValue(exceptionType);
+ }
+
+ /**
+ * Interprets a bytecode instruction without arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
+ * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, BIPUSH, SIPUSH, LDC, JSR,
+ * GETSTATIC, NEW
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V newOperation(AbstractInsnNode insn) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction that moves a value on the stack or to or from local
+ * variables. This method is called for the following opcodes:
+ *
+ * <p>ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, DUP, DUP_X1,
+ * DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the value that must be moved by the instruction.
+ * @return the result of the interpretation of the given instruction. The returned value must be
+ * {@code equal} to the given value.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V copyOperation(AbstractInsnNode insn, V value) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with a single argument. This method is called for the
+ * following opcodes:
+ *
+ * <p>INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F,
+ * I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN,
+ * FRETURN, DRETURN, ARETURN, PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW,
+ * CHECKCAST, INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V unaryOperation(AbstractInsnNode insn, V value) throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with two arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD,
+ * ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM,
+ * ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG,
+ * DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
+ * IF_ACMPNE, PUTFIELD
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value1 the first argument of the instruction to be interpreted.
+ * @param value2 the second argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with three arguments. This method is called for the following
+ * opcodes:
+ *
+ * <p>IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value1 the first argument of the instruction to be interpreted.
+ * @param value2 the second argument of the instruction to be interpreted.
+ * @param value3 the third argument of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V ternaryOperation(AbstractInsnNode insn, V value1, V value2, V value3)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode instruction with a variable number of arguments. This method is called
+ * for the following opcodes:
+ *
+ * <p>INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and
+ * INVOKEDYNAMIC
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param values the arguments of the instruction to be interpreted.
+ * @return the result of the interpretation of the given instruction.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract V naryOperation(AbstractInsnNode insn, List<? extends V> values)
+ throws AnalyzerException;
+
+ /**
+ * Interprets a bytecode return instruction. This method is called for the following opcodes:
+ *
+ * <p>IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
+ *
+ * @param insn the bytecode instruction to be interpreted.
+ * @param value the argument of the instruction to be interpreted.
+ * @param expected the expected return type of the analyzed method.
+ * @throws AnalyzerException if an error occurred during the interpretation.
+ */
+ public abstract void returnOperation(AbstractInsnNode insn, V value, V expected)
+ throws AnalyzerException;
+
+ /**
+ * Merges two values. The merge operation must return a value that represents both values (for
+ * instance, if the two values are two types, the merged value must be a common super type of the
+ * two types. If the two values are integer intervals, the merged value must be an interval that
+ * contains the previous ones. Likewise for other types of values).
+ *
+ * @param value1 a value.
+ * @param value2 another value.
+ * @return the merged value. If the merged value is equal to {@code value1}, this method
+ * <i>must</i> return {@code value1}.
+ */
+ public abstract V merge(V value1, V value2);
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java
new file mode 100644
index 00000000..a623bd09
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java
@@ -0,0 +1,381 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * An extended {@link BasicVerifier} that performs more precise verifications. This verifier
+ * computes exact class types, instead of using a single "object reference" type (as done in {@link
+ * BasicVerifier}).
+ *
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class SimpleVerifier extends BasicVerifier {
+
+ /** The type of the class that is verified. */
+ private final Type currentClass;
+
+ /** The type of the super class of the class that is verified. */
+ private final Type currentSuperClass;
+
+ /** The types of the interfaces directly implemented by the class that is verified. */
+ private final List<Type> currentClassInterfaces;
+
+ /** Whether the class that is verified is an interface. */
+ private final boolean isInterface;
+
+ /** The loader to use to load the referenced classes. */
+ private ClassLoader loader = getClass().getClassLoader();
+
+ /**
+ * Constructs a new {@link SimpleVerifier}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ */
+ public SimpleVerifier() {
+ this(null, null, false);
+ }
+
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ *
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ public SimpleVerifier(
+ final Type currentClass, final Type currentSuperClass, final boolean isInterface) {
+ this(currentClass, currentSuperClass, null, isInterface);
+ }
+
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SimpleVerifier(int, Type, Type, List, boolean)} version.
+ *
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param currentClassInterfaces the types of the interfaces directly implemented by the class to
+ * be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ public SimpleVerifier(
+ final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces,
+ final boolean isInterface) {
+ this(
+ /* latest api = */ ASM9,
+ currentClass,
+ currentSuperClass,
+ currentClassInterfaces,
+ isInterface);
+ if (getClass() != SimpleVerifier.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be
+ * loaded into the JVM since it may be incorrect.
+ *
+ * @param api the ASM API version supported by this verifier. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param currentClass the type of the class to be verified.
+ * @param currentSuperClass the type of the super class of the class to be verified.
+ * @param currentClassInterfaces the types of the interfaces directly implemented by the class to
+ * be verified.
+ * @param isInterface whether the class to be verifier is an interface.
+ */
+ protected SimpleVerifier(
+ final int api,
+ final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces,
+ final boolean isInterface) {
+ super(api);
+ this.currentClass = currentClass;
+ this.currentSuperClass = currentSuperClass;
+ this.currentClassInterfaces = currentClassInterfaces;
+ this.isInterface = isInterface;
+ }
+
+ /**
+ * Sets the <code>ClassLoader</code> to be used in {@link #getClass}.
+ *
+ * @param loader the <code>ClassLoader</code> to use.
+ */
+ public void setClassLoader(final ClassLoader loader) {
+ this.loader = loader;
+ }
+
+ @Override
+ public BasicValue newValue(final Type type) {
+ if (type == null) {
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+
+ boolean isArray = type.getSort() == Type.ARRAY;
+ if (isArray) {
+ switch (type.getElementType().getSort()) {
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ return new BasicValue(type);
+ default:
+ break;
+ }
+ }
+
+ BasicValue value = super.newValue(type);
+ if (BasicValue.REFERENCE_VALUE.equals(value)) {
+ if (isArray) {
+ value = newValue(type.getElementType());
+ StringBuilder descriptor = new StringBuilder();
+ for (int i = 0; i < type.getDimensions(); ++i) {
+ descriptor.append('[');
+ }
+ descriptor.append(value.getType().getDescriptor());
+ value = new BasicValue(Type.getType(descriptor.toString()));
+ } else {
+ value = new BasicValue(type);
+ }
+ }
+ return value;
+ }
+
+ @Override
+ protected boolean isArrayValue(final BasicValue value) {
+ Type type = value.getType();
+ return type != null && (type.getSort() == Type.ARRAY || type.equals(NULL_TYPE));
+ }
+
+ @Override
+ protected BasicValue getElementValue(final BasicValue objectArrayValue) throws AnalyzerException {
+ Type arrayType = objectArrayValue.getType();
+ if (arrayType != null) {
+ if (arrayType.getSort() == Type.ARRAY) {
+ return newValue(Type.getType(arrayType.getDescriptor().substring(1)));
+ } else if (arrayType.equals(NULL_TYPE)) {
+ return objectArrayValue;
+ }
+ }
+ throw new AssertionError();
+ }
+
+ @Override
+ protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+ Type expectedType = expected.getType();
+ Type type = value.getType();
+ switch (expectedType.getSort()) {
+ case Type.INT:
+ case Type.FLOAT:
+ case Type.LONG:
+ case Type.DOUBLE:
+ return type.equals(expectedType);
+ case Type.ARRAY:
+ case Type.OBJECT:
+ if (type.equals(NULL_TYPE)) {
+ return true;
+ } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ if (isAssignableFrom(expectedType, type)) {
+ return true;
+ } else if (getClass(expectedType).isInterface()) {
+ // The merge of class or interface types can only yield class types (because it is not
+ // possible in general to find an unambiguous common super interface, due to multiple
+ // inheritance). Because of this limitation, we need to relax the subtyping check here
+ // if 'value' is an interface.
+ return Object.class.isAssignableFrom(getClass(type));
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public BasicValue merge(final BasicValue value1, final BasicValue value2) {
+ if (!value1.equals(value2)) {
+ Type type1 = value1.getType();
+ Type type2 = value2.getType();
+ if (type1 != null
+ && (type1.getSort() == Type.OBJECT || type1.getSort() == Type.ARRAY)
+ && type2 != null
+ && (type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY)) {
+ if (type1.equals(NULL_TYPE)) {
+ return value2;
+ }
+ if (type2.equals(NULL_TYPE)) {
+ return value1;
+ }
+ if (isAssignableFrom(type1, type2)) {
+ return value1;
+ }
+ if (isAssignableFrom(type2, type1)) {
+ return value2;
+ }
+ int numDimensions = 0;
+ if (type1.getSort() == Type.ARRAY
+ && type2.getSort() == Type.ARRAY
+ && type1.getDimensions() == type2.getDimensions()
+ && type1.getElementType().getSort() == Type.OBJECT
+ && type2.getElementType().getSort() == Type.OBJECT) {
+ numDimensions = type1.getDimensions();
+ type1 = type1.getElementType();
+ type2 = type2.getElementType();
+ }
+ while (true) {
+ if (type1 == null || isInterface(type1)) {
+ return newArrayValue(Type.getObjectType("java/lang/Object"), numDimensions);
+ }
+ type1 = getSuperClass(type1);
+ if (isAssignableFrom(type1, type2)) {
+ return newArrayValue(type1, numDimensions);
+ }
+ }
+ }
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+ return value1;
+ }
+
+ private BasicValue newArrayValue(final Type type, final int dimensions) {
+ if (dimensions == 0) {
+ return newValue(type);
+ } else {
+ StringBuilder descriptor = new StringBuilder();
+ for (int i = 0; i < dimensions; ++i) {
+ descriptor.append('[');
+ }
+ descriptor.append(type.getDescriptor());
+ return newValue(Type.getType(descriptor.toString()));
+ }
+ }
+
+ /**
+ * Returns whether the given type corresponds to the type of an interface. The default
+ * implementation of this method loads the class and uses the reflection API to return its result
+ * (unless the given type corresponds to the class being verified).
+ *
+ * @param type a type.
+ * @return whether 'type' corresponds to an interface.
+ */
+ protected boolean isInterface(final Type type) {
+ if (currentClass != null && currentClass.equals(type)) {
+ return isInterface;
+ }
+ return getClass(type).isInterface();
+ }
+
+ /**
+ * Returns the type corresponding to the super class of the given type. The default implementation
+ * of this method loads the class and uses the reflection API to return its result (unless the
+ * given type corresponds to the class being verified).
+ *
+ * @param type a type.
+ * @return the type corresponding to the super class of 'type'.
+ */
+ protected Type getSuperClass(final Type type) {
+ if (currentClass != null && currentClass.equals(type)) {
+ return currentSuperClass;
+ }
+ Class<?> superClass = getClass(type).getSuperclass();
+ return superClass == null ? null : Type.getType(superClass);
+ }
+
+ /**
+ * Returns whether the class corresponding to the first argument is either the same as, or is a
+ * superclass or superinterface of the class corresponding to the second argument. The default
+ * implementation of this method loads the classes and uses the reflection API to return its
+ * result (unless the result can be computed from the class being verified, and the types of its
+ * super classes and implemented interfaces).
+ *
+ * @param type1 a type.
+ * @param type2 another type.
+ * @return whether the class corresponding to 'type1' is either the same as, or is a superclass or
+ * superinterface of the class corresponding to 'type2'.
+ */
+ protected boolean isAssignableFrom(final Type type1, final Type type2) {
+ if (type1.equals(type2)) {
+ return true;
+ }
+ if (currentClass != null && currentClass.equals(type1)) {
+ if (getSuperClass(type2) == null) {
+ return false;
+ } else {
+ if (isInterface) {
+ return type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY;
+ }
+ return isAssignableFrom(type1, getSuperClass(type2));
+ }
+ }
+ if (currentClass != null && currentClass.equals(type2)) {
+ if (isAssignableFrom(type1, currentSuperClass)) {
+ return true;
+ }
+ if (currentClassInterfaces != null) {
+ for (Type currentClassInterface : currentClassInterfaces) {
+ if (isAssignableFrom(type1, currentClassInterface)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ return getClass(type1).isAssignableFrom(getClass(type2));
+ }
+
+ /**
+ * Loads the class corresponding to the given type. The class is loaded with the class loader
+ * specified with {@link #setClassLoader}, or with the class loader of this class if no class
+ * loader was specified.
+ *
+ * @param type a type.
+ * @return the class corresponding to 'type'.
+ */
+ protected Class<?> getClass(final Type type) {
+ try {
+ if (type.getSort() == Type.ARRAY) {
+ return Class.forName(type.getDescriptor().replace('/', '.'), false, loader);
+ }
+ return Class.forName(type.getClassName(), false, loader);
+ } catch (ClassNotFoundException e) {
+ throw new TypeNotPresentException(e.toString(), e);
+ }
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java
new file mode 100644
index 00000000..4de24be7
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SmallSet.java
@@ -0,0 +1,198 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.AbstractSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * An immutable set of at most two elements, optimized for speed compared to a generic set
+ * implementation.
+ *
+ * @author Eric Bruneton
+ */
+final class SmallSet<T> extends AbstractSet<T> {
+
+ /** The first element of this set, maybe {@literal null}. */
+ private final T element1;
+
+ /**
+ * The second element of this set, maybe {@literal null}. If {@link #element1} is {@literal null}
+ * then this field must be {@literal null}, otherwise it must be different from {@link #element1}.
+ */
+ private final T element2;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructors
+ // -----------------------------------------------------------------------------------------------
+
+ /** Constructs an empty set. */
+ SmallSet() {
+ this.element1 = null;
+ this.element2 = null;
+ }
+
+ /**
+ * Constructs a set with exactly one element.
+ *
+ * @param element the unique set element.
+ */
+ SmallSet(final T element) {
+ this.element1 = element;
+ this.element2 = null;
+ }
+
+ /**
+ * Constructs a new {@link SmallSet}.
+ *
+ * @param element1 see {@link #element1}.
+ * @param element2 see {@link #element2}.
+ */
+ private SmallSet(final T element1, final T element2) {
+ this.element1 = element1;
+ this.element2 = element2;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the inherited abstract methods
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public Iterator<T> iterator() {
+ return new IteratorImpl<>(element1, element2);
+ }
+
+ @Override
+ public int size() {
+ if (element1 == null) {
+ return 0;
+ } else if (element2 == null) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the union of this set and of the given set.
+ *
+ * @param otherSet another small set.
+ * @return the union of this set and of otherSet.
+ */
+ Set<T> union(final SmallSet<T> otherSet) {
+ // If the two sets are equal, return this set.
+ if ((otherSet.element1 == element1 && otherSet.element2 == element2)
+ || (otherSet.element1 == element2 && otherSet.element2 == element1)) {
+ return this;
+ }
+ // If one set is empty, return the other.
+ if (otherSet.element1 == null) {
+ return this;
+ }
+ if (element1 == null) {
+ return otherSet;
+ }
+
+ // At this point we know that the two sets are non empty and are different.
+ // If otherSet contains exactly one element:
+ if (otherSet.element2 == null) {
+ // If this set also contains exactly one element, we have two distinct elements.
+ if (element2 == null) {
+ return new SmallSet<>(element1, otherSet.element1);
+ }
+ // If otherSet is included in this set, return this set.
+ if (otherSet.element1 == element1 || otherSet.element1 == element2) {
+ return this;
+ }
+ }
+ // If this set contains exactly one element, then otherSet contains two elements (because of the
+ // above tests). Thus, if otherSet contains this set, return otherSet:
+ if (element2 == null && (element1 == otherSet.element1 || element1 == otherSet.element2)) {
+ return otherSet;
+ }
+
+ // At this point we know that there are at least 3 distinct elements, so we need a generic set
+ // to store the result.
+ HashSet<T> result = new HashSet<>(4);
+ result.add(element1);
+ if (element2 != null) {
+ result.add(element2);
+ }
+ result.add(otherSet.element1);
+ if (otherSet.element2 != null) {
+ result.add(otherSet.element2);
+ }
+ return result;
+ }
+
+ static class IteratorImpl<T> implements Iterator<T> {
+
+ /** The next element to return in {@link #next}. Maybe {@literal null}. */
+ private T firstElement;
+
+ /**
+ * The element to return in {@link #next}, after {@link #firstElement} is returned. If {@link
+ * #firstElement} is {@literal null} then this field must be {@literal null}, otherwise it must
+ * be different from {@link #firstElement}.
+ */
+ private T secondElement;
+
+ IteratorImpl(final T firstElement, final T secondElement) {
+ this.firstElement = firstElement;
+ this.secondElement = secondElement;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return firstElement != null;
+ }
+
+ @Override
+ public T next() {
+ if (firstElement == null) {
+ throw new NoSuchElementException();
+ }
+ T element = firstElement;
+ firstElement = secondElement;
+ secondElement = null;
+ return element;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java
new file mode 100644
index 00000000..961ef9f2
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java
@@ -0,0 +1,220 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/**
+ * An {@link Interpreter} for {@link SourceValue} values.
+ *
+ * @author Eric Bruneton
+ */
+public class SourceInterpreter extends Interpreter<SourceValue> implements Opcodes {
+
+ /**
+ * Constructs a new {@link SourceInterpreter} for the latest ASM API version. <i>Subclasses must
+ * not use this constructor</i>. Instead, they must use the {@link #SourceInterpreter(int)}
+ * version.
+ */
+ public SourceInterpreter() {
+ super(/* latest api = */ ASM9);
+ if (getClass() != SourceInterpreter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link SourceInterpreter}.
+ *
+ * @param api the ASM API version supported by this interpreter. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected SourceInterpreter(final int api) {
+ super(api);
+ }
+
+ @Override
+ public SourceValue newValue(final Type type) {
+ if (type == Type.VOID_TYPE) {
+ return null;
+ }
+ return new SourceValue(type == null ? 1 : type.getSize());
+ }
+
+ @Override
+ public SourceValue newOperation(final AbstractInsnNode insn) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object value = ((LdcInsnNode) insn).cst;
+ size = value instanceof Long || value instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ break;
+ }
+ return new SourceValue(size, insn);
+ }
+
+ @Override
+ public SourceValue copyOperation(final AbstractInsnNode insn, final SourceValue value) {
+ return new SourceValue(value.getSize(), insn);
+ }
+
+ @Override
+ public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ break;
+ }
+ return new SourceValue(size, insn);
+ }
+
+ @Override
+ public SourceValue binaryOperation(
+ final AbstractInsnNode insn, final SourceValue value1, final SourceValue value2) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LALOAD:
+ case DALOAD:
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ default:
+ size = 1;
+ break;
+ }
+ return new SourceValue(size, insn);
+ }
+
+ @Override
+ public SourceValue ternaryOperation(
+ final AbstractInsnNode insn,
+ final SourceValue value1,
+ final SourceValue value2,
+ final SourceValue value3) {
+ return new SourceValue(1, insn);
+ }
+
+ @Override
+ public SourceValue naryOperation(
+ final AbstractInsnNode insn, final List<? extends SourceValue> values) {
+ int size;
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ size = 1;
+ } else if (opcode == INVOKEDYNAMIC) {
+ size = Type.getReturnType(((InvokeDynamicInsnNode) insn).desc).getSize();
+ } else {
+ size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize();
+ }
+ return new SourceValue(size, insn);
+ }
+
+ @Override
+ public void returnOperation(
+ final AbstractInsnNode insn, final SourceValue value, final SourceValue expected) {
+ // Nothing to do.
+ }
+
+ @Override
+ public SourceValue merge(final SourceValue value1, final SourceValue value2) {
+ if (value1.insns instanceof SmallSet && value2.insns instanceof SmallSet) {
+ Set<AbstractInsnNode> setUnion =
+ ((SmallSet<AbstractInsnNode>) value1.insns)
+ .union((SmallSet<AbstractInsnNode>) value2.insns);
+ if (setUnion == value1.insns && value1.size == value2.size) {
+ return value1;
+ } else {
+ return new SourceValue(Math.min(value1.size, value2.size), setUnion);
+ }
+ }
+ if (value1.size != value2.size || !containsAll(value1.insns, value2.insns)) {
+ HashSet<AbstractInsnNode> setUnion = new HashSet<>();
+ setUnion.addAll(value1.insns);
+ setUnion.addAll(value2.insns);
+ return new SourceValue(Math.min(value1.size, value2.size), setUnion);
+ }
+ return value1;
+ }
+
+ private static <E> boolean containsAll(final Set<E> self, final Set<E> other) {
+ if (self.size() < other.size()) {
+ return false;
+ }
+ return self.containsAll(other);
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java
new file mode 100644
index 00000000..540ccbbb
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceValue.java
@@ -0,0 +1,119 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.Set;
+import org.objectweb.asm.tree.AbstractInsnNode;
+
+/**
+ * A {@link Value} which keeps track of the bytecode instructions that can produce it.
+ *
+ * @author Eric Bruneton
+ */
+public class SourceValue implements Value {
+
+ /**
+ * The size of this value, in 32 bits words. This size is 1 for byte, boolean, char, short, int,
+ * float, object and array types, and 2 for long and double.
+ */
+ public final int size;
+
+ /**
+ * The instructions that can produce this value. For example, for the Java code below, the
+ * instructions that can produce the value of {@code i} at line 5 are the two ISTORE instructions
+ * at line 1 and 3:
+ *
+ * <pre>
+ * 1: i = 0;
+ * 2: if (...) {
+ * 3: i = 1;
+ * 4: }
+ * 5: return i;
+ * </pre>
+ */
+ public final Set<AbstractInsnNode> insns;
+
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ */
+ public SourceValue(final int size) {
+ this(size, new SmallSet<>());
+ }
+
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ * @param insnNode an instruction that can produce this value.
+ */
+ public SourceValue(final int size, final AbstractInsnNode insnNode) {
+ this.size = size;
+ this.insns = new SmallSet<>(insnNode);
+ }
+
+ /**
+ * Constructs a new {@link SourceValue}.
+ *
+ * @param size the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ * @param insnSet the instructions that can produce this value.
+ */
+ public SourceValue(final int size, final Set<AbstractInsnNode> insnSet) {
+ this.size = size;
+ this.insns = insnSet;
+ }
+
+ /**
+ * Returns the size of this value.
+ *
+ * @return the size of this value, in 32 bits words. This size is 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ */
+ @Override
+ public int getSize() {
+ return size;
+ }
+
+ @Override
+ public boolean equals(final Object value) {
+ if (!(value instanceof SourceValue)) {
+ return false;
+ }
+ SourceValue sourceValue = (SourceValue) value;
+ return size == sourceValue.size && insns.equals(sourceValue.insns);
+ }
+
+ @Override
+ public int hashCode() {
+ return insns.hashCode();
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Subroutine.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Subroutine.java
new file mode 100644
index 00000000..a6ca806b
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Subroutine.java
@@ -0,0 +1,106 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+
+/**
+ * A method subroutine (corresponds to a JSR instruction).
+ *
+ * @author Eric Bruneton
+ */
+final class Subroutine {
+
+ /** The start of this subroutine. */
+ final LabelNode start;
+
+ /**
+ * The local variables that are read or written by this subroutine. The i-th element is true if
+ * and only if the local variable at index i is read or written by this subroutine.
+ */
+ final boolean[] localsUsed;
+
+ /** The JSR instructions that jump to this subroutine. */
+ final List<JumpInsnNode> callers;
+
+ /**
+ * Constructs a new {@link Subroutine}.
+ *
+ * @param start the start of this subroutine.
+ * @param maxLocals the local variables that are read or written by this subroutine.
+ * @param caller a JSR instruction that jump to this subroutine.
+ */
+ Subroutine(final LabelNode start, final int maxLocals, final JumpInsnNode caller) {
+ this.start = start;
+ this.localsUsed = new boolean[maxLocals];
+ this.callers = new ArrayList<>();
+ callers.add(caller);
+ }
+
+ /**
+ * Constructs a copy of the given {@link Subroutine}.
+ *
+ * @param subroutine the subroutine to copy.
+ */
+ Subroutine(final Subroutine subroutine) {
+ this.start = subroutine.start;
+ this.localsUsed = subroutine.localsUsed.clone();
+ this.callers = new ArrayList<>(subroutine.callers);
+ }
+
+ /**
+ * Merges the given subroutine into this subroutine. The local variables read or written by the
+ * given subroutine are marked as read or written by this one, and the callers of the given
+ * subroutine are added as callers of this one (if both have the same start).
+ *
+ * @param subroutine another subroutine. This subroutine is left unchanged by this method.
+ * @return whether this subroutine has been modified by this method.
+ */
+ public boolean merge(final Subroutine subroutine) {
+ boolean changed = false;
+ for (int i = 0; i < localsUsed.length; ++i) {
+ if (subroutine.localsUsed[i] && !localsUsed[i]) {
+ localsUsed[i] = true;
+ changed = true;
+ }
+ }
+ if (subroutine.start == start) {
+ for (int i = 0; i < subroutine.callers.size(); ++i) {
+ JumpInsnNode caller = subroutine.callers.get(i);
+ if (!callers.contains(caller)) {
+ callers.add(caller);
+ changed = true;
+ }
+ }
+ }
+ return changed;
+ }
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Value.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Value.java
new file mode 100644
index 00000000..669f075f
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Value.java
@@ -0,0 +1,44 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+/**
+ * An immutable symbolic value for the semantic interpretation of bytecode.
+ *
+ * @author Eric Bruneton
+ */
+public interface Value {
+
+ /**
+ * Returns the size of this value in 32 bits words. This size should be 1 for byte, boolean, char,
+ * short, int, float, object and array types, and 2 for long and double.
+ *
+ * @return either 1 or 2.
+ */
+ int getSize();
+}
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/package.html b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/package.html
new file mode 100644
index 00000000..05624f6a
--- /dev/null
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/package.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm.tree.analysis</title>
+</head>
+<body>
+
+<p>
+Provides a framework for static code analysis based on the asm.tree package.
+</p>
+
+<p>
+Basic usage:
+</p>
+
+<pre>
+ClassReader classReader = new ClassReader(bytecode);
+ClassNode classNode = new ClassNode();
+classReader.accept(classNode, ClassReader.SKIP_DEBUG);
+
+for (MethodNode method : classNode.methods) {
+ if (method.instructions.size() > 0) {
+ Analyzer analyzer = new Analyzer(new BasicInterpreter());
+ analyzer.analyze(classNode.name, method);
+ Frame[] frames = analyzer.getFrames();
+ // Elements of the frames array now contains info for each instruction
+ // from the analyzed method. BasicInterpreter creates BasicValue, that
+ // is using simplified type system that distinguishes the UNINITIALZED,
+ // INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types.
+ ...
+ }
+}
+</pre>
+
+<p>
+@since ASM 1.4.3
+</p>
+
+</body>
+</html>
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java
new file mode 100644
index 00000000..e0ff13bf
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java
@@ -0,0 +1,1274 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link Analyzer}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerTest extends AsmTest {
+
+ private static final String CLASS_NAME = "C";
+
+ // Some local variable numbers used in tests.
+ private static final int LOCAL1 = 1;
+ private static final int LOCAL2 = 2;
+ private static final int LOCAL3 = 3;
+ private static final int LOCAL4 = 4;
+ private static final int LOCAL5 = 5;
+
+ // Labels used to generate test cases.
+ private final Label label0 = new Label();
+ private final Label label1 = new Label();
+ private final Label label2 = new Label();
+ private final Label label3 = new Label();
+ private final Label label4 = new Label();
+ private final Label label5 = new Label();
+ private final Label label6 = new Label();
+ private final Label label7 = new Label();
+ private final Label label8 = new Label();
+ private final Label label9 = new Label();
+ private final Label label10 = new Label();
+ private final Label label11 = new Label();
+ private final Label label12 = new Label();
+
+ @Test
+ void testAnalyze_invalidOpcode() {
+ MethodNode methodNode = new MethodNodeBuilder().insn(-1).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal opcode -1"));
+ }
+
+ @Test
+ void testAnalyze_invalidPop() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().insn(Opcodes.LCONST_0).insn(Opcodes.POP).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of POP"));
+ }
+
+ @Test
+ void testAnalyze_invalidPop2() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.POP2)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of POP2"));
+ }
+
+ @Test
+ void testAnalyze_invalidDup() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().insn(Opcodes.LCONST_0).insn(Opcodes.DUP).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP"));
+ }
+
+ @Test
+ void testAnalyze_invalidDupx1() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.DUP_X1)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP_X1"));
+ }
+
+ @Test
+ void testAnalyze_invalidDupx2() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.DUP_X2)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP_X2"));
+ }
+
+ @Test
+ void testAnalyze_invalidDup2() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.DUP2)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP2"));
+ }
+
+ @Test
+ void testAnalyze_invalidDup2x1() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.DUP2_X1)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP2_X1"));
+ }
+
+ @Test
+ void testAnalyze_invalidDup2x2() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.DUP2_X2)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of DUP2_X2"));
+ }
+
+ @Test
+ void testAnalyze_invalidSwap() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.SWAP)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Illegal use of SWAP"));
+ }
+
+ @Test
+ void testAnalyze_invalidGetLocal() {
+ MethodNode methodNode = new MethodNodeBuilder().aload(10).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Trying to get an inexistant local variable"));
+ }
+
+ @Test
+ void testAnalyze_invalidSetLocal() {
+ MethodNode methodNode = new MethodNodeBuilder().aconst_null().astore(10).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Trying to set an inexistant local variable"));
+ }
+
+ @Test
+ void testAnalyze_invalidPopFromEmptyStack() {
+ MethodNode methodNode = new MethodNodeBuilder().insn(Opcodes.POP).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Cannot pop operand off an empty stack."));
+ }
+
+ @Test
+ void testAnalyze_invalidPushOnFullStack() {
+ MethodNode methodNode =
+ new MethodNodeBuilder(3, 3).iconst_0().iconst_0().iconst_0().iconst_0().vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Insufficient maximum stack size."));
+ }
+
+ @Test
+ void testAnalyze_inconsistentStackHeights() {
+ Label ifLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .iconst_0()
+ .ifne(ifLabel)
+ .iconst_0()
+ .label(ifLabel)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Incompatible stack heights"));
+ }
+
+ @Test
+ void testAnalyze_invalidRet() {
+ MethodNode methodNode = new MethodNodeBuilder().ret(1).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("RET instruction outside of a subroutine"));
+ }
+
+ @Test
+ void testAnalyze_invalidFalloffEndOfMethod() {
+ MethodNode methodNode = new MethodNodeBuilder().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Execution can fall off the end of the code"));
+ }
+
+ @Test
+ void testAnalyze_invalidFalloffSubroutine() {
+ Label gotoLabel = new Label();
+ Label jsrLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .go(gotoLabel)
+ .label(jsrLabel)
+ .astore(1)
+ .ret(1)
+ .label(gotoLabel)
+ .jsr(jsrLabel)
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Execution can fall off the end of the code"));
+ }
+
+ @Disabled("TODO currently Analyzer can not detect this situation")
+ @Test
+ void testAnalyze_invalidOverlappingSubroutines() {
+ // The problem is that other overlapping subroutine situations are valid, such as
+ // when a nested subroutine implicitly returns to its parent subroutine, without a RET.
+ Label subroutine1Label = new Label();
+ Label subroutine2Label = new Label();
+ Label endSubroutineLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .jsr(subroutine1Label)
+ .jsr(subroutine2Label)
+ .vreturn()
+ .label(subroutine1Label)
+ .astore(1)
+ .go(endSubroutineLabel)
+ .label(subroutine2Label)
+ .astore(1)
+ .label(endSubroutineLabel)
+ .ret(1)
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ assertThrows(AnalyzerException.class, analyze);
+ }
+
+ /**
+ * Tests a method which has the most basic <code>try{}finally{}</code> form imaginable. That is:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * a--;
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_basicTryFinally() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(4, 4)
+ .iconst_0()
+ .istore(1)
+ // Body of try block.
+ .label(label0)
+ .iinc(1, 1)
+ .go(label3)
+ // Exception handler.
+ .label(label1)
+ .astore(3)
+ .jsr(label2)
+ .aload(3)
+ .athrow()
+ // Subroutine.
+ .label(label2)
+ .astore(2)
+ .iinc(1, -1)
+ .push()
+ .push()
+ .ret(2)
+ // Non-exceptional exit from try block.
+ .label(label3)
+ .jsr(label2)
+ .push()
+ .push()
+ .label(label4)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label1)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests a method which has an if/else-if w/in the finally clause. More specifically:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * if (a == 0) {
+ * a += 2;
+ * } else {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_ifElseInFinally() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(5, 4)
+ .iconst_0()
+ .istore(1)
+ // Body of try block.
+ .label(label0)
+ .iinc(1, 1)
+ .go(label5)
+ // Exception handler.
+ .label(label1)
+ .astore(3)
+ .jsr(label2)
+ .push()
+ .push()
+ .aload(3)
+ .athrow()
+ // Subroutine.
+ .label(label2)
+ .astore(2)
+ .push()
+ .push()
+ .iload(1)
+ .ifne(label3)
+ .iinc(1, 2)
+ .go(label4)
+ .label(label3)
+ .iinc(1, 3)
+ .label(label4)
+ .ret(2)
+ // Non-exceptional exit from try block.
+ .label(label5)
+ .jsr(label2)
+ .label(label6)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label5, label6, label1)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests a simple nested finally. More specifically:
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * try {
+ * a += 1;
+ * } finally {
+ * try {
+ * a += 2;
+ * } finally {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_simpleNestedFinally() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(5, 6)
+ .iconst_0()
+ .istore(1)
+ // Body of try block.
+ .label(label0)
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label5)
+ // First exception handler.
+ .label(label1)
+ .astore(4)
+ .jsr(label2)
+ .aload(4)
+ .athrow()
+ // First subroutine.
+ .label(label2)
+ .astore(2)
+ .iinc(1, 2)
+ .jsr(label4)
+ .push()
+ .push()
+ .ret(2)
+ // Second exception handler.
+ .label(label3)
+ .astore(5)
+ .jsr(label4)
+ .aload(5)
+ .athrow()
+ // Second subroutine.
+ .label(label4)
+ .astore(3)
+ .push()
+ .push()
+ .iinc(1, 3)
+ .ret(3)
+ // On normal exit, try block jumps here.
+ .label(label5)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label2, label3, label3)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ @Test
+ void testAnalyze_nestedSubroutines() throws AnalyzerException {
+ Label subroutine1Label = new Label();
+ Label subroutine2Label = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 3)
+ .jsr(subroutine1Label)
+ .vreturn()
+ .label(subroutine1Label)
+ .astore(1)
+ .jsr(subroutine2Label)
+ .jsr(subroutine2Label)
+ .ret(1)
+ .label(subroutine2Label)
+ .astore(2)
+ .ret(2)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead.
+ *
+ * <p>We structure this as a try/finally with a break in the finally. Because the while loop is
+ * infinite, it's clear from the byte code that the only path which reaches the RETURN instruction
+ * is through the subroutine.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (true) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_subroutineWithNoRet() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ // While loop header/try block.
+ .label(label0)
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label3)
+ // Implicit catch block.
+ .label(label1)
+ .astore(2)
+ .jsr(label2)
+ .push()
+ .push()
+ .aload(2)
+ .athrow()
+ // Subroutine which does not return.
+ .label(label2)
+ .astore(3)
+ .iinc(1, 2)
+ .go(label4)
+ // End of the loop, goes back to the top.
+ .label(label3)
+ .go(label0)
+ .label(label4)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead.
+ *
+ * <pre>
+ * aconst_null
+ * jsr l0
+ * l0:
+ * astore 0
+ * astore 0
+ * return
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_subroutineWithNoRet2() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(2, 2)
+ .aconst_null()
+ .jsr(label0)
+ .nop()
+ .label(label0)
+ .astore(0)
+ .astore(0)
+ .vreturn()
+ .label(label1)
+ .localVariable("i", "I", null, label0, label1, 1)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ @Test
+ void testAnalyze_subroutineLocalsAccess() throws AnalyzerException {
+ Label startLabel = new Label();
+ Label exceptionHandler1Label = new Label();
+ Label exceptionHandler2Label = new Label();
+ Label subroutineLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 5)
+ .label(startLabel)
+ .jsr(subroutineLabel)
+ .vreturn()
+ .label(exceptionHandler1Label)
+ .astore(1)
+ .jsr(subroutineLabel)
+ .aload(1)
+ .athrow()
+ .label(subroutineLabel)
+ .astore(2)
+ .aconst_null()
+ .astore(3)
+ .ret(2)
+ .label(exceptionHandler2Label)
+ .astore(4)
+ .aload(4)
+ .athrow()
+ .trycatch(startLabel, exceptionHandler1Label, exceptionHandler1Label)
+ .trycatch(
+ startLabel,
+ exceptionHandler2Label,
+ exceptionHandler2Label,
+ "java/lang/RuntimeException")
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but instead exits implicitly by branching
+ * to code which is not part of the subroutine. (Sadly, this is legal)
+ *
+ * <p>We structure this as a try/finally in a loop with a break in the finally. The loop is not
+ * trivially infinite, so the RETURN statement is reachable both from the JSR subroutine and from
+ * the main entry point.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (null == null) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_implicitExit() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ // While loop header.
+ .label(label0)
+ .aconst_null()
+ .ifnonnull(label5)
+ // Try block.
+ .label(label1)
+ .iinc(1, 1)
+ .jsr(label3)
+ .go(label4)
+ // Implicit catch block.
+ .label(label2)
+ .astore(2)
+ .jsr(label3)
+ .aload(2)
+ .push()
+ .push()
+ .athrow()
+ // Subroutine which does not return.
+ .label(label3)
+ .astore(3)
+ .iinc(1, 2)
+ .go(label5)
+ // End of the loop, goes back to the top.
+ .label(label4)
+ .go(label1)
+ .label(label5)
+ .vreturn()
+ .trycatch(label1, label2, label2)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine.
+ * Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(boolean b) {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>This example is from the paper, "Subroutine Inlining and Bytecode Abstraction to Simplify
+ * Static and Dynamic Analysis" by Cyrille Artho and Armin Biere.
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_implicitExitToAnotherSubroutine() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(5, 6)
+ .iconst_0()
+ .istore(1)
+ // First try.
+ .label(label0)
+ .jsr(label2)
+ .vreturn()
+ // Exception handler for first try.
+ .label(label1)
+ .astore(LOCAL2)
+ .jsr(label2)
+ .push()
+ .push()
+ .aload(LOCAL2)
+ .athrow()
+ // First finally handler.
+ .label(label2)
+ .astore(LOCAL4)
+ .push()
+ .push()
+ .go(label6)
+ // Body of while loop, also second try.
+ .label(label3)
+ .jsr(label5)
+ .vreturn()
+ // Exception handler for second try.
+ .label(label4)
+ .astore(LOCAL3)
+ .push()
+ .push()
+ .jsr(label5)
+ .aload(LOCAL3)
+ .athrow()
+ // Second finally handler.
+ .label(label5)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label7)
+ .ret(LOCAL5)
+ // Test for the while loop.
+ .label(label6)
+ .iload(LOCAL1)
+ .ifne(label3)
+ // Exit from finally block.
+ .label(label7)
+ .ret(LOCAL4)
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label4)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ @Test
+ void testanalyze_implicitExitToAnotherSubroutine2() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .jsr(label0)
+ .vreturn()
+ .label(label0)
+ .astore(2)
+ .jsr(label1)
+ .go(label2)
+ .label(label1)
+ .astore(3)
+ .iload(1)
+ .ifne(label2)
+ .ret(3)
+ .label(label2)
+ .ret(2)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * This tests a simple subroutine where the control flow jumps back and forth between the
+ * subroutine and the caller.
+ *
+ * <p>This would not normally be produced by a java compiler.
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_interleavedCode() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(4, 3)
+ .iconst_0()
+ .istore(1)
+ .jsr(label0)
+ .go(label1)
+ // Subroutine 1.
+ .label(label0)
+ .astore(2)
+ .iinc(1, 1)
+ .go(label2)
+ // Second part of main subroutine.
+ .label(label1)
+ .iinc(1, 2)
+ .go(label3)
+ // Second part of subroutine 1.
+ .label(label2)
+ .iinc(1, 4)
+ .push()
+ .push()
+ .ret(2)
+ // Third part of main subroutine.
+ .label(label3)
+ .push()
+ .push()
+ .vreturn()
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine, and
+ * with a surrounding try/catch thrown in the mix. Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(int b) {
+ * try {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * } catch (Exception e) {
+ * b += 3;
+ * return;
+ * }
+ * }
+ * </pre>
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_implicitExitInTryCatch() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(4, 6)
+ .iconst_0()
+ .istore(1)
+ // First try.
+ .label(label0)
+ .jsr(label2)
+ .vreturn()
+ // Exception handler for first try.
+ .label(label1)
+ .astore(LOCAL2)
+ .jsr(label2)
+ .aload(LOCAL2)
+ .athrow()
+ // First finally handler.
+ .label(label2)
+ .astore(LOCAL4)
+ .go(label6)
+ // Body of while loop, also second try.
+ .label(label3)
+ .jsr(label5)
+ .push()
+ .push()
+ .vreturn()
+ // Exception handler for second try.
+ .label(label4)
+ .astore(LOCAL3)
+ .jsr(label5)
+ .aload(LOCAL3)
+ .athrow()
+ // Second finally handler.
+ .label(label5)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label7)
+ .push()
+ .push()
+ .ret(LOCAL5)
+ // Test for the while loop.
+ .label(label6)
+ .iload(LOCAL1)
+ .ifne(label3)
+ // Exit from finally{} block.
+ .label(label7)
+ .ret(LOCAL4)
+ // Outermost catch.
+ .label(label8)
+ .iinc(LOCAL1, 3)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label4)
+ .trycatch(label0, label8, label8)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests that Analyzer works correctly on classes with many labels.
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_manyLabels() throws AnalyzerException {
+ Label target = new Label();
+ MethodNodeBuilder methodNodeBuilder = new MethodNodeBuilder(1, 1).jsr(target).label(target);
+ for (int i = 0; i < 8192; i++) {
+ Label label = new Label();
+ methodNodeBuilder.go(label).label(label);
+ }
+ MethodNode methodNode = methodNodeBuilder.vreturn().build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests an example coming from distilled down version of
+ * com/sun/corba/ee/impl/protocol/CorbaClientDelegateImpl from GlassFish 2. See issue #317823.
+ *
+ * @throws AnalyzerException if the test fails
+ */
+ @Test
+ void testAnalyze_glassFish2CorbaClientDelegateImplExample() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder(3, 3)
+ .label(label0)
+ .jsr(label4)
+ .label(label1)
+ .go(label5)
+ .label(label2)
+ .pop()
+ .jsr(label4)
+ .label(label3)
+ .aconst_null()
+ .athrow()
+ .label(label4)
+ .astore(1)
+ .ret(1)
+ .label(label5)
+ .aconst_null()
+ .aconst_null()
+ .aconst_null()
+ .pop()
+ .pop()
+ .pop()
+ .label(label6)
+ .go(label8)
+ .label(label7)
+ .pop()
+ .go(label8)
+ .aconst_null()
+ .athrow()
+ .label(label8)
+ .iconst_0()
+ .ifne(label0)
+ .jsr(label12)
+ .label(label9)
+ .vreturn()
+ .label(label10)
+ .pop()
+ .jsr(label12)
+ .label(label11)
+ .aconst_null()
+ .athrow()
+ .label(label12)
+ .astore(2)
+ .ret(2)
+ .trycatch(label0, label1, label2)
+ .trycatch(label2, label3, label2)
+ .trycatch(label0, label6, label7)
+ .trycatch(label0, label9, label10)
+ .trycatch(label10, label11, label10)
+ .build();
+
+ Frame<?>[] frames = newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ MethodMaxs methodMaxs = computeMaxStackAndLocalsFromFrames(frames);
+ assertEquals(methodNode.maxStack, methodMaxs.maxStack);
+ assertEquals(methodNode.maxLocals, methodMaxs.maxLocals);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ private static Analyzer<MockValue> newAnalyzer() {
+ return new Analyzer<>(new MockInterpreter());
+ }
+
+ private static MethodMaxs computeMaxStackAndLocalsFromFrames(final Frame<?>[] frames) {
+ int maxStack = 0;
+ int maxLocals = 0;
+ for (Frame<?> frame : frames) {
+ if (frame != null) {
+ int stackSize = 0;
+ for (int i = 0; i < frame.getStackSize(); ++i) {
+ stackSize += frame.getStack(i).getSize();
+ }
+ maxStack = Math.max(maxStack, stackSize);
+ maxLocals = Math.max(maxLocals, frame.getLocals());
+ }
+ }
+ return new MethodMaxs(maxStack, maxLocals);
+ }
+
+ private static class MethodMaxs {
+
+ public final int maxStack;
+ public final int maxLocals;
+
+ public MethodMaxs(final int maxStack, final int maxLocals) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+ }
+
+ private static enum MockValue implements Value {
+ INT,
+ LONG,
+ REFERENCE,
+ RETURN_ADDRESS,
+ TOP;
+
+ @Override
+ public int getSize() {
+ return equals(LONG) ? 2 : 1;
+ }
+ }
+
+ private static class MockInterpreter extends Interpreter<MockValue> {
+
+ MockInterpreter() {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+ }
+
+ @Override
+ public MockValue newValue(final Type type) {
+ if (type == null) {
+ return MockValue.TOP;
+ }
+ switch (type.getSort()) {
+ case Type.VOID:
+ return null;
+ case Type.INT:
+ return MockValue.INT;
+ case Type.LONG:
+ return MockValue.INT;
+ case Type.OBJECT:
+ return MockValue.REFERENCE;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public MockValue newOperation(final AbstractInsnNode insn) {
+ switch (insn.getOpcode()) {
+ case Opcodes.ACONST_NULL:
+ return MockValue.REFERENCE;
+ case Opcodes.ICONST_0:
+ return MockValue.INT;
+ case Opcodes.JSR:
+ return MockValue.RETURN_ADDRESS;
+ case Opcodes.LCONST_0:
+ return MockValue.LONG;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public MockValue copyOperation(final AbstractInsnNode insn, final MockValue value) {
+ return value;
+ }
+
+ @Override
+ public MockValue unaryOperation(final AbstractInsnNode insn, final MockValue value) {
+ switch (insn.getOpcode()) {
+ case Opcodes.IFNE:
+ case Opcodes.IFNONNULL:
+ case Opcodes.ATHROW:
+ return null;
+ case Opcodes.IINC:
+ return MockValue.INT;
+ case Opcodes.NEWARRAY:
+ return MockValue.REFERENCE;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public MockValue binaryOperation(
+ final AbstractInsnNode insn, final MockValue value1, final MockValue value2) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public MockValue ternaryOperation(
+ final AbstractInsnNode insn,
+ final MockValue value1,
+ final MockValue value2,
+ final MockValue value3) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public MockValue naryOperation(
+ final AbstractInsnNode insn, final List<? extends MockValue> values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void returnOperation(
+ final AbstractInsnNode insn, final MockValue value, final MockValue expected) {
+ // Nothing to do.
+ }
+
+ @Override
+ public MockValue merge(final MockValue value1, final MockValue value2) {
+ if (!value1.equals(value2)) {
+ return MockValue.TOP;
+ }
+ return value1;
+ }
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java
new file mode 100644
index 00000000..fc199934
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java
@@ -0,0 +1,256 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static java.time.Duration.ofSeconds;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.AsmTest.PrecompiledClass;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link Analyzer}, when used with a {@link BasicInterpreter}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerWithBasicInterpreterTest extends AsmTest {
+
+ private static final String CLASS_NAME = "C";
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new BasicInterpreter());
+ assertThrows(IllegalStateException.class, () -> new BasicInterpreter() {});
+ }
+
+ @Test
+ void testAnalyze_invalidNewArray() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().iconst_0().intInsn(Opcodes.NEWARRAY, -1).vreturn().build();
+
+ Executable analyze =
+ () -> new Analyzer<BasicValue>(new BasicInterpreter()).analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Invalid array type"));
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed with a BasicInterpreter, and
+ * that Analyzer can be subclassed to use custom frames.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyze_basicInterpreter(final PrecompiledClass classParameter, final Api apiParameter)
+ throws AnalyzerException {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ Analyzer<BasicValue> analyzer =
+ new Analyzer<BasicValue>(new BasicInterpreter()) {
+ @Override
+ protected Frame<BasicValue> newFrame(final int numLocals, final int numStack) {
+ return new CustomFrame(numLocals, numStack);
+ }
+
+ @Override
+ protected Frame<BasicValue> newFrame(final Frame<? extends BasicValue> src) {
+ return new CustomFrame(src);
+ }
+ };
+
+ ArrayList<Frame<? extends BasicValue>[]> methodFrames = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ methodFrames.add(analyzer.analyze(classNode.name, methodNode));
+ }
+
+ for (Frame<? extends BasicValue>[] frames : methodFrames) {
+ for (Frame<? extends BasicValue> frame : frames) {
+ assertTrue(frame == null || frame instanceof CustomFrame);
+ }
+ }
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed with a BasicInterpreter, even
+ * if the method node's max locals and max stack size are not set.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyzeAndComputeMaxs_basicInterpreter(
+ final PrecompiledClass classParameter, final Api apiParameter) throws AnalyzerException {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ ArrayList<MethodMaxs> methodMaxs = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ methodMaxs.add(new MethodMaxs(methodNode.maxStack, methodNode.maxLocals));
+ methodNode.maxLocals = 0;
+ methodNode.maxStack = 0;
+ }
+ Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new BasicInterpreter());
+
+ ArrayList<MethodMaxs> analyzedMethodMaxs = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ analyzer.analyzeAndComputeMaxs(classNode.name, methodNode);
+ analyzedMethodMaxs.add(new MethodMaxs(methodNode.maxStack, methodNode.maxLocals));
+ }
+
+ // jdk3.SubOptimalMaxStackAndLocals has non optimal max stack and max local values on purpose.
+ assumeTrue(classParameter != PrecompiledClass.JDK3_SUB_OPTIMAL_MAX_STACK_AND_LOCALS);
+ for (int i = 0; i < analyzedMethodMaxs.size(); ++i) {
+ assertTrue(analyzedMethodMaxs.get(i).maxLocals >= methodMaxs.get(i).maxLocals);
+ assertTrue(analyzedMethodMaxs.get(i).maxStack >= methodMaxs.get(i).maxStack);
+ }
+ }
+
+ /**
+ * Tests that analyzeAndComputeMaxs computes the smallest possible maxLocals for static methods.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @Test
+ void testAnalyzeAndComputeMaxs_staticMethod() throws AnalyzerException {
+ MethodNode methodNode =
+ new MethodNodeBuilder("(I)V", /* maxStack = */ 0, /* maxLocals = */ 0).vreturn().build();
+ methodNode.access |= Opcodes.ACC_STATIC;
+ Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new BasicInterpreter());
+
+ analyzer.analyzeAndComputeMaxs("C", methodNode);
+
+ assertEquals(1, methodNode.maxLocals);
+ assertEquals(0, methodNode.maxStack);
+ }
+
+ /**
+ * Tests that the analyzer does not loop infinitely, even if the {@link Interpreter#merge} method
+ * does not follow its required contract (namely that if the merge result is equal to the first
+ * argument, the first argument should be returned - see #316326).
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @Test
+ void testAnalyze_badInterpreter() {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(PrecompiledClass.JDK8_ALL_FRAMES.getBytes()).accept(classNode, 0);
+ Analyzer<BasicValue> analyzer =
+ new Analyzer<BasicValue>(
+ new BasicInterpreter(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+ @Override
+ public BasicValue merge(final BasicValue value1, final BasicValue value2) {
+ return new BasicValue(super.merge(value1, value2).getType());
+ }
+ });
+
+ ArrayList<Executable> analyses = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ analyses.add(() -> analyzer.analyze(CLASS_NAME, methodNode));
+ }
+
+ for (Executable analysis : analyses) {
+ assertTimeoutPreemptively(ofSeconds(1), analysis);
+ }
+ }
+
+ /**
+ * Tests that stack map frames are correctly merged when a JSR instruction can be reached from two
+ * different control flow paths, with different local variable types (#316204).
+ *
+ * @throws IOException if the test class can't be loaded.
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @Test
+ void testAnalyze_mergeWithJsrReachableFromTwoDifferentPaths()
+ throws IOException, AnalyzerException {
+ ClassReader classReader =
+ new ClassReader(Files.newInputStream(Paths.get("src/test/resources/Issue316204.class")));
+ ClassNode classNode = new ClassNode();
+ classReader.accept(classNode, 0);
+ Analyzer<BasicValue> analyzer = new Analyzer<>(new BasicInterpreter());
+
+ analyzer.analyze(classNode.name, getMethod(classNode, "basicStopBundles"));
+
+ assertEquals("RIR..... ", analyzer.getFrames()[104].toString());
+ }
+
+ private static MethodNode getMethod(final ClassNode classNode, final String name) {
+ for (MethodNode methodNode : classNode.methods) {
+ if (methodNode.name.equals(name)) {
+ return methodNode;
+ }
+ }
+ return null;
+ }
+
+ private static class CustomFrame extends Frame<BasicValue> {
+
+ CustomFrame(final int numLocals, final int numStack) {
+ super(numLocals, numStack);
+ }
+
+ CustomFrame(final Frame<? extends BasicValue> frame) {
+ super(frame);
+ }
+
+ @Override
+ public Frame<BasicValue> init(final Frame<? extends BasicValue> frame) {
+ assertTrue(frame instanceof CustomFrame);
+ return super.init(frame);
+ }
+ }
+
+ private static class MethodMaxs {
+
+ public final int maxStack;
+ public final int maxLocals;
+
+ public MethodMaxs(final int maxStack, final int maxLocals) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicVerifierTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicVerifierTest.java
new file mode 100644
index 00000000..8a09544f
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicVerifierTest.java
@@ -0,0 +1,243 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link Analyzer}, when used with a {@link BasicVerifier}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerWithBasicVerifierTest extends AsmTest {
+
+ private static final String CLASS_NAME = "C";
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new BasicVerifier());
+ assertThrows(IllegalStateException.class, () -> new BasicVerifier() {});
+ }
+
+ @Test
+ void testAnalyze_invalidAload() {
+ MethodNode methodNode = new MethodNodeBuilder().iconst_0().istore(1).aload(1).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected an object reference, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidAstore() {
+ MethodNode methodNode = new MethodNodeBuilder().iconst_0().astore(1).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected an object reference or a return address, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidIstore() {
+ MethodNode methodNode = new MethodNodeBuilder().aconst_null().istore(1).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains(" Expected I, but found R"));
+ }
+
+ @Test
+ void testAnalyze_invalidCheckcast() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .iconst_0()
+ .typeInsn(Opcodes.CHECKCAST, "java/lang/String")
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected an object reference, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidArraylength() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().iconst_0().insn(Opcodes.ARRAYLENGTH).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected an array reference, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidAthrow() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().iconst_0().insn(Opcodes.ATHROW).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected an object reference, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidIneg() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().insn(Opcodes.FCONST_0).insn(Opcodes.INEG).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Expected I, but found F"));
+ }
+
+ @Test
+ void testAnalyze_invalidIadd() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.FCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.IADD)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("First argument: expected I, but found F"));
+ }
+
+ @Test
+ void testAnalyze_invalidIastore() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.ICONST_1)
+ .intInsn(Opcodes.NEWARRAY, Opcodes.T_INT)
+ .insn(Opcodes.FCONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.IASTORE)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Second argument: expected I, but found F"));
+ }
+
+ @Test
+ void testAnalyze_invalidFastore() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.ICONST_1)
+ .intInsn(Opcodes.NEWARRAY, Opcodes.T_FLOAT)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.FASTORE)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Third argument: expected F, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidLastore() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.ICONST_1)
+ .insn(Opcodes.ICONST_0)
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.LASTORE)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("First argument: expected a R array reference, but found I"));
+ }
+
+ @Test
+ void testAnalyze_invalidMultianewarray() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.FCONST_1)
+ .insn(Opcodes.ICONST_2)
+ .multiANewArrayInsn("[[I", 2)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertEquals("Error at instruction 2: Expected I, but found F", message);
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed with a BasicVerifier.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyze_basicVerifier(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ Analyzer<BasicValue> analyzer = newAnalyzer();
+
+ for (MethodNode methodNode : classNode.methods) {
+ assertDoesNotThrow(() -> analyzer.analyze(classNode.name, methodNode));
+ }
+ }
+
+ private static Analyzer<BasicValue> newAnalyzer() {
+ return new Analyzer<>(new BasicVerifier());
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSimpleVerifierTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSimpleVerifierTest.java
new file mode 100644
index 00000000..99505a9f
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSimpleVerifierTest.java
@@ -0,0 +1,201 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link Analyzer}, when used with a {@link SimpleVerifier}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerWithSimpleVerifierTest extends AsmTest {
+
+ private static final String CLASS_NAME = "C";
+
+ @Test
+ void testAnalyze_invalidInvokevirtual() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.ACONST_NULL)
+ .typeInsn(Opcodes.CHECKCAST, "java/lang/Object")
+ .methodInsn(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "size", "()I", false)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains(
+ "Method owner: expected Ljava/util/ArrayList;, but found Ljava/lang/Object;"));
+ }
+
+ @Test
+ void testAnalyze_invalidInvokeinterface() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .insn(Opcodes.ACONST_NULL)
+ .typeInsn(Opcodes.CHECKCAST, "java/util/List")
+ .insn(Opcodes.FCONST_0)
+ .methodInsn(
+ Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertEquals("Error at instruction 3: Argument 1: expected I, but found F", message);
+ }
+
+ @Test
+ void testAnalyze_classNotFound() {
+ Label loopLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .aload(0)
+ .astore(1)
+ .label(loopLabel)
+ .aconst_null()
+ .typeInsn(Opcodes.CHECKCAST, "D")
+ .astore(1)
+ .go(loopLabel)
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Type java.lang.ClassNotFoundException: D not present"));
+ }
+
+ @Test
+ void testAnalyze_mergeStackFrames() throws AnalyzerException {
+ Label loopLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder(1, 4)
+ .aload(0)
+ .astore(1)
+ .aconst_null()
+ .typeInsn(Opcodes.CHECKCAST, "java/lang/Number")
+ .astore(2)
+ .aload(0)
+ .astore(3)
+ .label(loopLabel)
+ .aconst_null()
+ .typeInsn(Opcodes.CHECKCAST, "java/lang/Number")
+ .astore(1)
+ .aload(0)
+ .astore(2)
+ .aconst_null()
+ .typeInsn(Opcodes.CHECKCAST, "java/lang/Integer")
+ .astore(3)
+ .go(loopLabel)
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ assertDoesNotThrow(analyze);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed with a SimpleVerifier.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyze_simpleVerifier(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ assumeFalse(classNode.methods.isEmpty());
+ Analyzer<BasicValue> analyzer =
+ new Analyzer<BasicValue>(
+ new SimpleVerifier(
+ Type.getObjectType(classNode.name),
+ Type.getObjectType(classNode.superName),
+ (classNode.access & Opcodes.ACC_INTERFACE) != 0));
+
+ for (MethodNode methodNode : classNode.methods) {
+ assertDoesNotThrow(() -> analyzer.analyze(classNode.name, methodNode));
+ }
+ }
+
+ /**
+ * Checks that the merge of an ArrayList and an SQLException can be returned as an Iterable. The
+ * merged type is recomputed by SimpleVerifier as Object (because of limitations of the merging
+ * algorithm, due to multiple interface inheritance), but the subtyping check is relaxed if the
+ * super type is an interface type.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @Test
+ void testIsAssignableFrom_interface() throws AnalyzerException {
+ Label elseLabel = new Label();
+ Label endIfLabel = new Label();
+ MethodNode methodNode =
+ new MethodNodeBuilder(
+ "(Ljava/util/ArrayList;Ljava/sql/SQLException;)Ljava/lang/Iterable;", 1, 3)
+ .aload(1)
+ .ifnonnull(elseLabel)
+ .aload(1)
+ .go(endIfLabel)
+ .label(elseLabel)
+ .aload(2)
+ .label(endIfLabel)
+ .areturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ assertDoesNotThrow(analyze);
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(methodNode).newInstance());
+ }
+
+ private static Analyzer<BasicValue> newAnalyzer() {
+ return new Analyzer<>(
+ new SimpleVerifier(Type.getType("LC;"), Type.getType("Ljava/lang/Number;"), false));
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSourceInterpreterTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSourceInterpreterTest.java
new file mode 100644
index 00000000..5d4a205e
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithSourceInterpreterTest.java
@@ -0,0 +1,71 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link Analyzer}, when used with a {@link SourceInterpreter}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerWithSourceInterpreterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new SourceInterpreter());
+ assertThrows(IllegalStateException.class, () -> new SourceInterpreter() {});
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed with a SourceInterpreter.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyze_sourceInterpreter(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ Analyzer<SourceValue> analyzer = new Analyzer<>(new SourceInterpreter());
+
+ for (MethodNode methodNode : classNode.methods) {
+ assertDoesNotThrow(() -> analyzer.analyze(classNode.name, methodNode));
+ }
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicValueTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicValueTest.java
new file mode 100644
index 00000000..e35e4459
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/BasicValueTest.java
@@ -0,0 +1,80 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Type;
+
+/**
+ * Unit tests for {@link BasicValue}.
+ *
+ * @author Eric Bruneton
+ */
+class BasicValueTest {
+
+ @Test
+ void testIsReference() {
+ assertTrue(BasicValue.REFERENCE_VALUE.isReference());
+ assertTrue(new BasicValue(Type.getObjectType("[I")).isReference());
+ assertFalse(BasicValue.UNINITIALIZED_VALUE.isReference());
+ assertFalse(BasicValue.INT_VALUE.isReference());
+ }
+
+ @Test
+ void testEquals() {
+ boolean equalsSameUninitializedValue =
+ new BasicValue(null).equals(BasicValue.UNINITIALIZED_VALUE);
+ boolean equalsSameValue = new BasicValue(Type.INT_TYPE).equals(BasicValue.INT_VALUE);
+ boolean equalsThis = BasicValue.INT_VALUE.equals(BasicValue.INT_VALUE);
+ boolean equalsDifferentClass = BasicValue.INT_VALUE.equals(new Object());
+
+ assertTrue(equalsSameUninitializedValue);
+ assertTrue(equalsSameValue);
+ assertTrue(equalsThis);
+ assertFalse(equalsDifferentClass);
+ }
+
+ @Test
+ void testHashCode() {
+ assertEquals(0, BasicValue.UNINITIALIZED_VALUE.hashCode());
+ assertNotEquals(0, BasicValue.INT_VALUE.hashCode());
+ }
+
+ @Test
+ void testToString() {
+ assertEquals(".", BasicValue.UNINITIALIZED_VALUE.toString());
+ assertEquals("A", BasicValue.RETURNADDRESS_VALUE.toString());
+ assertEquals("R", BasicValue.REFERENCE_VALUE.toString());
+ assertEquals("LI;", new BasicValue(Type.getObjectType("I")).toString());
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/MethodNodeBuilder.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/MethodNodeBuilder.java
new file mode 100644
index 00000000..6051488a
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/MethodNodeBuilder.java
@@ -0,0 +1,227 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * A builder of {@link MethodNode}, to construct test cases for unit tests.
+ *
+ * @author Eric Bruneton
+ */
+final class MethodNodeBuilder {
+
+ private final MethodNode methodNode;
+
+ MethodNodeBuilder() {
+ this(10, 10);
+ }
+
+ MethodNodeBuilder(final int maxStack, final int maxLocals) {
+ this("()V", maxStack, maxLocals);
+ }
+
+ MethodNodeBuilder(final String descriptor, final int maxStack, final int maxLocals) {
+ methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "m", descriptor, null, null);
+ methodNode.maxStack = maxStack;
+ methodNode.maxLocals = maxLocals;
+ methodNode.visitCode();
+ }
+
+ MethodNodeBuilder insn(final int opcode) {
+ methodNode.visitInsn(opcode);
+ return this;
+ }
+
+ MethodNodeBuilder intInsn(final int opcode, final int operand) {
+ methodNode.visitIntInsn(opcode, operand);
+ return this;
+ }
+
+ MethodNodeBuilder typeInsn(final int opcode, final String operand) {
+ methodNode.visitTypeInsn(opcode, operand);
+ return this;
+ }
+
+ MethodNodeBuilder methodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ methodNode.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ return this;
+ }
+
+ MethodNodeBuilder multiANewArrayInsn(final String descriptor, final int numDimensions) {
+ methodNode.visitMultiANewArrayInsn(descriptor, numDimensions);
+ return this;
+ }
+
+ MethodNodeBuilder nop() {
+ methodNode.visitInsn(Opcodes.NOP);
+ return this;
+ }
+
+ MethodNodeBuilder push() {
+ methodNode.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ MethodNodeBuilder pop() {
+ methodNode.visitInsn(Opcodes.POP);
+ return this;
+ }
+
+ MethodNodeBuilder iconst_0() {
+ methodNode.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ MethodNodeBuilder istore(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ISTORE, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder aload(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ALOAD, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder iload(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ILOAD, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder astore(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ASTORE, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder ret(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.RET, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder athrow() {
+ methodNode.visitInsn(Opcodes.ATHROW);
+ return this;
+ }
+
+ MethodNodeBuilder aconst_null() {
+ methodNode.visitInsn(Opcodes.ACONST_NULL);
+ return this;
+ }
+
+ MethodNodeBuilder areturn() {
+ methodNode.visitInsn(Opcodes.ARETURN);
+ return this;
+ }
+
+ MethodNodeBuilder vreturn() {
+ methodNode.visitInsn(Opcodes.RETURN);
+ return this;
+ }
+
+ MethodNodeBuilder label(final Label label) {
+ methodNode.visitLabel(label);
+ return this;
+ }
+
+ MethodNodeBuilder iinc(final int varIndex, final int increment) {
+ methodNode.visitIincInsn(varIndex, increment);
+ return this;
+ }
+
+ MethodNodeBuilder go(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.GOTO, label);
+ return this;
+ }
+
+ MethodNodeBuilder jsr(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.JSR, label);
+ return this;
+ }
+
+ MethodNodeBuilder ifnonnull(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.IFNONNULL, label);
+ return this;
+ }
+
+ MethodNodeBuilder ifne(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.IFNE, label);
+ return this;
+ }
+
+ MethodNodeBuilder trycatch(final Label start, final Label end, final Label handler) {
+ return trycatch(start, end, handler, null);
+ }
+
+ MethodNodeBuilder trycatch(
+ final Label start, final Label end, final Label handler, final String type) {
+ methodNode.visitTryCatchBlock(start, end, handler, type);
+ return this;
+ }
+
+ MethodNodeBuilder localVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ methodNode.visitLocalVariable(name, descriptor, signature, start, end, index);
+ return this;
+ }
+
+ MethodNode build() {
+ methodNode.visitEnd();
+ return methodNode;
+ }
+
+ static ClassFile buildClassWithMethod(final MethodNode methodNode) {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ methodNode.accept(classWriter);
+ return new ClassFile(classWriter.toByteArray());
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java
new file mode 100644
index 00000000..4faa857e
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java
@@ -0,0 +1,135 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Unit tests for {@link SimpleVerifier}.
+ *
+ * @author Eric Bruneton
+ */
+class SimpleVerifierTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new SimpleVerifier());
+ assertThrows(IllegalStateException.class, () -> new SimpleVerifier() {});
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "java/lang/String, java/lang/Number, java/lang/Object",
+ "java/lang/Integer, java/lang/Number, java/lang/Number",
+ "java/lang/Float, java/lang/Integer, java/lang/Number",
+ "java/lang/Long, java/util/List, java/lang/Object",
+ "java/util/Map, java/util/List, java/lang/Object"
+ })
+ void testMerge_objectTypes(
+ final String internalName1, final String internalName2, final String expectedInternalName) {
+ BasicValue value1 = new BasicValue(Type.getObjectType(internalName1));
+ BasicValue value2 = new BasicValue(Type.getObjectType(internalName2));
+ SimpleVerifier verifier = new SimpleVerifier();
+
+ BasicValue merge1 = verifier.merge(value1, value2);
+ BasicValue merge2 = verifier.merge(value2, value1);
+
+ BasicValue expectedValue = new BasicValue(Type.getObjectType(expectedInternalName));
+ assertEquals(expectedValue, merge1);
+ assertEquals(expectedValue, merge2);
+ }
+
+ @Test
+ void testIsAssignableFrom_subclassWithInterfaces() {
+ Type baseType = Type.getObjectType("C");
+ Type superType = Type.getObjectType("D");
+ Type interfaceType = Type.getObjectType("I");
+ SimpleVerifier simpleVerifier =
+ new SimpleVerifier(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL,
+ baseType,
+ superType,
+ Arrays.asList(interfaceType),
+ false) {
+
+ @Override
+ public boolean isAssignableFrom(final Type type1, final Type type2) {
+ return super.isAssignableFrom(type1, type2);
+ }
+
+ @Override
+ protected Class<?> getClass(final Type type) {
+ // Return dummy classes, to make sure isAssignable in test() does not rely on them.
+ if (type == baseType) {
+ return int.class;
+ }
+ if (type == superType) {
+ return float.class;
+ }
+ if (type == interfaceType) {
+ return double.class;
+ }
+ return super.getClass(type);
+ }
+ };
+
+ assertTrue(simpleVerifier.isAssignableFrom(baseType, baseType));
+ assertTrue(simpleVerifier.isAssignableFrom(superType, baseType));
+ assertTrue(simpleVerifier.isAssignableFrom(interfaceType, baseType));
+ }
+
+ @Test
+ void testIsAssignableFrom_interface() {
+ Type baseType = Type.getObjectType("C");
+ Type interfaceType = Type.getObjectType("I");
+ SimpleVerifier simpleVerifier =
+ new SimpleVerifier(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL, interfaceType, null, null, true) {
+
+ @Override
+ protected Type getSuperClass(final Type type) {
+ return Type.getObjectType("java/lang/Object");
+ }
+ };
+
+ assertTrue(simpleVerifier.isAssignableFrom(interfaceType, baseType));
+ assertTrue(simpleVerifier.isAssignableFrom(interfaceType, Type.getObjectType("[I")));
+ assertFalse(simpleVerifier.isAssignableFrom(interfaceType, Type.INT_TYPE));
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SmallSetTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SmallSetTest.java
new file mode 100644
index 00000000..12691fbf
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SmallSetTest.java
@@ -0,0 +1,171 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link SmallSet}.
+ *
+ * @author Eric Bruneton
+ */
+class SmallSetTest {
+
+ private static final Object ELEMENT1 = new Object();
+ private static final Object ELEMENT2 = new Object();
+ private static final Object ELEMENT3 = new Object();
+ private static final Object ELEMENT4 = new Object();
+
+ @Test
+ void testUnion_oneElement_emptySet() {
+ SmallSet<Object> set1 = new SmallSet<>(ELEMENT1);
+ SmallSet<Object> set2 = new SmallSet<>();
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(set1, union1);
+ assertEquals(set1, union2);
+ }
+
+ @Test
+ void testUnion_oneElement_oneElement() {
+ SmallSet<Object> set1 = new SmallSet<>(ELEMENT1);
+ SmallSet<Object> set2 = new SmallSet<>(ELEMENT1);
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(union1, union2);
+ assertEquals(union1, new HashSet<Object>(Arrays.asList(ELEMENT1)));
+ }
+
+ @Test
+ void testUnion_oneElement_twoElements_superSet() {
+ SmallSet<Object> set1 = newSmallSet(ELEMENT1, ELEMENT2);
+ SmallSet<Object> set2 = new SmallSet<>(ELEMENT1);
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(union1, union2);
+ assertEquals(union1, new HashSet<Object>(Arrays.asList(ELEMENT1, ELEMENT2)));
+ }
+
+ @Test
+ void testUnion_twoElements_twoElements_equalSets() {
+ SmallSet<Object> set1 = newSmallSet(ELEMENT1, ELEMENT2);
+ SmallSet<Object> set2 = newSmallSet(ELEMENT2, ELEMENT1);
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(union1, union2);
+ assertEquals(union1, new HashSet<Object>(Arrays.asList(ELEMENT1, ELEMENT2)));
+ }
+
+ @Test
+ void testUnion_twoElements_oneElement_distinctSets() {
+ SmallSet<Object> set1 = newSmallSet(ELEMENT1, ELEMENT2);
+ SmallSet<Object> set2 = new SmallSet<>(ELEMENT3);
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(union1, union2);
+ assertEquals(union1, new HashSet<Object>(Arrays.asList(ELEMENT1, ELEMENT2, ELEMENT3)));
+ }
+
+ @Test
+ void testUnion_twoElements_twoElements_distincSets() {
+ SmallSet<Object> set1 = newSmallSet(ELEMENT1, ELEMENT2);
+ SmallSet<Object> set2 = newSmallSet(ELEMENT3, ELEMENT4);
+
+ Set<Object> union1 = set1.union(set2);
+ Set<Object> union2 = set2.union(set1);
+
+ assertEquals(union1, union2);
+ assertEquals(
+ union1, new HashSet<Object>(Arrays.asList(ELEMENT1, ELEMENT2, ELEMENT3, ELEMENT4)));
+ }
+
+ @Test
+ void testIterator_next_firstElement() {
+ Iterator<Object> iterator = newSmallSet(ELEMENT1, ELEMENT2).iterator();
+
+ Object element = iterator.next();
+
+ assertEquals(ELEMENT1, element);
+ assertTrue(iterator.hasNext());
+ }
+
+ @Test
+ void testIterator_next_secondElement() {
+ Iterator<Object> iterator = newSmallSet(ELEMENT1, ELEMENT2).iterator();
+ iterator.next();
+
+ Object element = iterator.next();
+
+ assertEquals(ELEMENT2, element);
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ void testIterator_next_noSuchElement() {
+ Iterator<Object> iterator = newSmallSet(ELEMENT1, ELEMENT2).iterator();
+ iterator.next();
+ iterator.next();
+
+ Executable next = () -> iterator.next();
+
+ assertThrows(NoSuchElementException.class, next);
+ }
+
+ @Test
+ void testIterator_remove() {
+ Iterator<Object> iterator = newSmallSet(ELEMENT1, ELEMENT2).iterator();
+ iterator.next();
+
+ assertThrows(UnsupportedOperationException.class, () -> iterator.remove());
+ }
+
+ private static SmallSet<Object> newSmallSet(final Object element1, final Object element2) {
+ return (SmallSet<Object>) new SmallSet<Object>(element1).union(new SmallSet<Object>(element2));
+ }
+}
diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SourceValueTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SourceValueTest.java
new file mode 100644
index 00000000..a6c8dccf
--- /dev/null
+++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SourceValueTest.java
@@ -0,0 +1,72 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.InsnNode;
+
+/**
+ * Unit tests for {@link SourceValue} tests.
+ *
+ * @author Eric Bruneton
+ */
+class SourceValueTest {
+
+ @Test
+ void testGetSize() {
+ assertEquals(2, new SourceValue(2).getSize());
+ }
+
+ @Test
+ void testEquals() {
+ SourceValue nullValue = null;
+
+ boolean equalsSame = new SourceValue(1).equals(new SourceValue(1));
+ boolean equalsValueWithDifferentSource =
+ new SourceValue(1).equals(new SourceValue(1, new InsnNode(Opcodes.NOP)));
+ boolean equalsValueWithDifferentValue = new SourceValue(1).equals(new SourceValue(2));
+ boolean equalsNull = new SourceValue(1).equals(nullValue);
+
+ assertTrue(equalsSame);
+ assertFalse(equalsValueWithDifferentSource);
+ assertFalse(equalsValueWithDifferentValue);
+ assertFalse(equalsNull);
+ }
+
+ @Test
+ void testHashcode() {
+ assertEquals(0, new SourceValue(1).hashCode());
+ assertNotEquals(0, new SourceValue(1, new InsnNode(Opcodes.NOP)).hashCode());
+ }
+}
diff --git a/asm-analysis/src/test/resources/Issue316204.class b/asm-analysis/src/test/resources/Issue316204.class
new file mode 100644
index 00000000..964f522d
--- /dev/null
+++ b/asm-analysis/src/test/resources/Issue316204.class
Binary files differ
diff --git a/asm-analysis/src/test/resources/sigtest-4.0.txt b/asm-analysis/src/test/resources/sigtest-4.0.txt
new file mode 100644
index 00000000..95d44cc7
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-4.0.txt
@@ -0,0 +1,436 @@
+#Signature file v4.1
+#Version 4.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer
+cons public init(org.objectweb.asm.tree.analysis.Interpreter)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame newFrame(org.objectweb.asm.tree.analysis.Frame)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,insns,interpreter,n,queue,queued,subroutines,top
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame,org.objectweb.asm.tree.analysis.Interpreter) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame init(org.objectweb.asm.tree.analysis.Frame)
+meth public org.objectweb.asm.tree.analysis.Value getLocal(int)
+meth public org.objectweb.asm.tree.analysis.Value getStack(int)
+meth public org.objectweb.asm.tree.analysis.Value pop()
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void push(org.objectweb.asm.tree.analysis.Value)
+meth public void setLocal(int,org.objectweb.asm.tree.analysis.Value)
+meth public void setReturn(org.objectweb.asm.tree.analysis.Value)
+supr java.lang.Object
+hfds locals,returnValue,top,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter
+cons protected init(int)
+fld protected final int api
+meth public abstract org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public abstract org.objectweb.asm.tree.analysis.Value naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value newValue(org.objectweb.asm.Type)
+meth public abstract org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds class$java$lang$Object,currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-5.0.txt b/asm-analysis/src/test/resources/sigtest-5.0.txt
new file mode 100644
index 00000000..6914a11e
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-5.0.txt
@@ -0,0 +1,440 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer
+cons public init(org.objectweb.asm.tree.analysis.Interpreter)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame newFrame(org.objectweb.asm.tree.analysis.Frame)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,insns,interpreter,n,queue,queued,subroutines,top
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame,org.objectweb.asm.tree.analysis.Interpreter) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame init(org.objectweb.asm.tree.analysis.Frame)
+meth public org.objectweb.asm.tree.analysis.Value getLocal(int)
+meth public org.objectweb.asm.tree.analysis.Value getStack(int)
+meth public org.objectweb.asm.tree.analysis.Value pop()
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void push(org.objectweb.asm.tree.analysis.Value)
+meth public void setLocal(int,org.objectweb.asm.tree.analysis.Value)
+meth public void setReturn(org.objectweb.asm.tree.analysis.Value)
+supr java.lang.Object
+hfds locals,returnValue,top,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter
+cons protected init(int)
+fld protected final int api
+meth public abstract org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public abstract org.objectweb.asm.tree.analysis.Value naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value newValue(org.objectweb.asm.Type)
+meth public abstract org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds class$java$lang$Object,currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.Value binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value merge(org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value)
+meth public org.objectweb.asm.tree.analysis.Value ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Value unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Value,org.objectweb.asm.tree.analysis.Value) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-6.0.txt b/asm-analysis/src/test/resources/sigtest-6.0.txt
new file mode 100644
index 00000000..b05d037d
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-6.0.txt
@@ -0,0 +1,430 @@
+#Signature file v4.1
+#Version 6.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,insns,interpreter,n,queue,queued,subroutines,top
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds locals,returnValue,top,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-6.1.txt b/asm-analysis/src/test/resources/sigtest-6.1.txt
new file mode 100644
index 00000000..708618e3
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-6.1.txt
@@ -0,0 +1,433 @@
+#Signature file v4.1
+#Version 6.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds nLocals,nStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-7.0.txt b/asm-analysis/src/test/resources/sigtest-7.0.txt
new file mode 100644
index 00000000..178c07be
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-7.0.txt
@@ -0,0 +1,443 @@
+#Signature file v4.1
+#Version 7.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-7.2.txt b/asm-analysis/src/test/resources/sigtest-7.2.txt
new file mode 100644
index 00000000..e0e53d88
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-7.2.txt
@@ -0,0 +1,447 @@
+#Signature file v4.1
+#Version 7.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-7.3.1.txt b/asm-analysis/src/test/resources/sigtest-7.3.1.txt
new file mode 100644
index 00000000..1d28fb17
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-7.3.1.txt
@@ -0,0 +1,448 @@
+#Signature file v4.1
+#Version 7.3.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-8.0.1.txt b/asm-analysis/src/test/resources/sigtest-8.0.1.txt
new file mode 100644
index 00000000..b32a9ba4
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-8.0.1.txt
@@ -0,0 +1,450 @@
+#Signature file v4.1
+#Version 8.0.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-9.0.txt b/asm-analysis/src/test/resources/sigtest-9.0.txt
new file mode 100644
index 00000000..5e8a1b8d
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-9.0.txt
@@ -0,0 +1,452 @@
+#Signature file v4.1
+#Version 9.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-9.1.txt b/asm-analysis/src/test/resources/sigtest-9.1.txt
new file mode 100644
index 00000000..55932adb
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-9.1.txt
@@ -0,0 +1,454 @@
+#Signature file v4.1
+#Version 9.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyzeAndComputeMaxs(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds MAX_STACK_SIZE,maxStack,numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-9.2.txt b/asm-analysis/src/test/resources/sigtest-9.2.txt
new file mode 100644
index 00000000..edabbd64
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-9.2.txt
@@ -0,0 +1,455 @@
+#Signature file v4.1
+#Version 9.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyzeAndComputeMaxs(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds MAX_STACK_SIZE,maxStack,numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-analysis/src/test/resources/sigtest-9.4.txt b/asm-analysis/src/test/resources/sigtest-9.4.txt
new file mode 100644
index 00000000..f600616a
--- /dev/null
+++ b/asm-analysis/src/test/resources/sigtest-9.4.txt
@@ -0,0 +1,458 @@
+#Signature file v4.1
+#Version 9.4
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM10_EXPERIMENTAL = 17432576
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V19 = 63
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V20 = 64
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public org.objectweb.asm.tree.analysis.Analyzer<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Analyzer%0}>)
+intf org.objectweb.asm.Opcodes
+meth protected boolean newControlFlowExceptionEdge(int,int)
+meth protected boolean newControlFlowExceptionEdge(int,org.objectweb.asm.tree.TryCatchBlockNode)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(int,int)
+meth protected org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}> newFrame(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Analyzer%0}>)
+meth protected void init(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth protected void newControlFlowEdge(int,int)
+meth public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> getHandlers(int)
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyze(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] analyzeAndComputeMaxs(java.lang.String,org.objectweb.asm.tree.MethodNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Analyzer%0}>[] getFrames()
+supr java.lang.Object
+hfds frames,handlers,inInstructionsToProcess,insnList,insnListSize,instructionsToProcess,interpreter,numInstructionsToProcess,subroutines
+
+CLSS public org.objectweb.asm.tree.analysis.AnalyzerException
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Object,org.objectweb.asm.tree.analysis.Value)
+cons public init(org.objectweb.asm.tree.AbstractInsnNode,java.lang.String,java.lang.Throwable)
+fld public final org.objectweb.asm.tree.AbstractInsnNode node
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.analysis.BasicInterpreter
+cons protected init(int)
+cons public init()
+fld public final static org.objectweb.asm.Type NULL_TYPE
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.BasicValue>
+
+CLSS public org.objectweb.asm.tree.analysis.BasicValue
+cons public init(org.objectweb.asm.Type)
+fld public final static org.objectweb.asm.tree.analysis.BasicValue DOUBLE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue FLOAT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue INT_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue LONG_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue REFERENCE_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue RETURNADDRESS_VALUE
+fld public final static org.objectweb.asm.tree.analysis.BasicValue UNINITIALIZED_VALUE
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public boolean isReference()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getType()
+supr java.lang.Object
+hfds type
+
+CLSS public org.objectweb.asm.tree.analysis.BasicVerifier
+cons protected init(int)
+cons public init()
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.BasicValue>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+supr org.objectweb.asm.tree.analysis.BasicInterpreter
+
+CLSS public org.objectweb.asm.tree.analysis.Frame<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons public init(int,int)
+cons public init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,boolean[])
+meth public boolean merge(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public int getLocals()
+meth public int getMaxStackSize()
+meth public int getStackSize()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Frame%0}> init(org.objectweb.asm.tree.analysis.Frame<? extends {org.objectweb.asm.tree.analysis.Frame%0}>)
+meth public void clearStack()
+meth public void execute(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.Interpreter<{org.objectweb.asm.tree.analysis.Frame%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public void initJumpTarget(int,org.objectweb.asm.tree.LabelNode)
+meth public void push({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setLocal(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setReturn({org.objectweb.asm.tree.analysis.Frame%0})
+meth public void setStack(int,{org.objectweb.asm.tree.analysis.Frame%0})
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getLocal(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} getStack(int)
+meth public {org.objectweb.asm.tree.analysis.Frame%0} pop()
+supr java.lang.Object
+hfds MAX_STACK_SIZE,maxStack,numLocals,numStack,returnValue,values
+
+CLSS public abstract org.objectweb.asm.tree.analysis.Interpreter<%0 extends org.objectweb.asm.tree.analysis.Value>
+cons protected init(int)
+fld protected final int api
+meth public abstract void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} copyOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} merge({org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0})
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends {org.objectweb.asm.tree.analysis.Interpreter%0}>) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newOperation(org.objectweb.asm.tree.AbstractInsnNode) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} newValue(org.objectweb.asm.Type)
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0},{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public abstract {org.objectweb.asm.tree.analysis.Interpreter%0} unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,{org.objectweb.asm.tree.analysis.Interpreter%0}) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newEmptyValue(int)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newExceptionValue(org.objectweb.asm.tree.TryCatchBlockNode,org.objectweb.asm.tree.analysis.Frame<{org.objectweb.asm.tree.analysis.Interpreter%0}>,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newParameterValue(boolean,int,org.objectweb.asm.Type)
+meth public {org.objectweb.asm.tree.analysis.Interpreter%0} newReturnTypeValue(org.objectweb.asm.Type)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.analysis.SimpleVerifier
+cons protected init(int,org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+cons public init()
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,boolean)
+cons public init(org.objectweb.asm.Type,org.objectweb.asm.Type,java.util.List<org.objectweb.asm.Type>,boolean)
+meth protected boolean isArrayValue(org.objectweb.asm.tree.analysis.BasicValue)
+meth protected boolean isAssignableFrom(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth protected boolean isInterface(org.objectweb.asm.Type)
+meth protected boolean isSubTypeOf(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth protected java.lang.Class<?> getClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.Type getSuperClass(org.objectweb.asm.Type)
+meth protected org.objectweb.asm.tree.analysis.BasicValue getElementValue(org.objectweb.asm.tree.analysis.BasicValue) throws org.objectweb.asm.tree.analysis.AnalyzerException
+meth public org.objectweb.asm.tree.analysis.BasicValue merge(org.objectweb.asm.tree.analysis.BasicValue,org.objectweb.asm.tree.analysis.BasicValue)
+meth public org.objectweb.asm.tree.analysis.BasicValue newValue(org.objectweb.asm.Type)
+meth public void setClassLoader(java.lang.ClassLoader)
+supr org.objectweb.asm.tree.analysis.BasicVerifier
+hfds currentClass,currentClassInterfaces,currentSuperClass,isInterface,loader
+
+CLSS public org.objectweb.asm.tree.analysis.SourceInterpreter
+cons protected init(int)
+cons public init()
+intf org.objectweb.asm.Opcodes
+meth public org.objectweb.asm.tree.analysis.SourceValue binaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue copyOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue merge(org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue naryOperation(org.objectweb.asm.tree.AbstractInsnNode,java.util.List<? extends org.objectweb.asm.tree.analysis.SourceValue>)
+meth public org.objectweb.asm.tree.analysis.SourceValue newOperation(org.objectweb.asm.tree.AbstractInsnNode)
+meth public org.objectweb.asm.tree.analysis.SourceValue newValue(org.objectweb.asm.Type)
+meth public org.objectweb.asm.tree.analysis.SourceValue ternaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+meth public org.objectweb.asm.tree.analysis.SourceValue unaryOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue)
+meth public void returnOperation(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.analysis.SourceValue,org.objectweb.asm.tree.analysis.SourceValue)
+supr org.objectweb.asm.tree.analysis.Interpreter<org.objectweb.asm.tree.analysis.SourceValue>
+
+CLSS public org.objectweb.asm.tree.analysis.SourceValue
+cons public init(int)
+cons public init(int,java.util.Set<org.objectweb.asm.tree.AbstractInsnNode>)
+cons public init(int,org.objectweb.asm.tree.AbstractInsnNode)
+fld public final int size
+fld public final java.util.Set<org.objectweb.asm.tree.AbstractInsnNode> insns
+intf org.objectweb.asm.tree.analysis.Value
+meth public boolean equals(java.lang.Object)
+meth public int getSize()
+meth public int hashCode()
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.tree.analysis.Value
+meth public abstract int getSize()
+
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AdviceAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AdviceAdapter.java
new file mode 100644
index 00000000..8f1ad1b8
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AdviceAdapter.java
@@ -0,0 +1,670 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link MethodVisitor} to insert before, after and around advices in methods and constructors.
+ * For constructors, the code keeps track of the elements on the stack in order to detect when the
+ * super class constructor is called (note that there can be multiple such calls in different
+ * branches). {@code onMethodEnter} is called after each super class constructor call, because the
+ * object cannot be used before it is properly initialized.
+ *
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes {
+
+ /** The "uninitialized this" value. */
+ private static final Object UNINITIALIZED_THIS = new Object();
+
+ /** Any value other than "uninitialized this". */
+ private static final Object OTHER = new Object();
+
+ /** Prefix of the error message when invalid opcodes are found. */
+ private static final String INVALID_OPCODE = "Invalid opcode ";
+
+ /** The access flags of the visited method. */
+ protected int methodAccess;
+
+ /** The descriptor of the visited method. */
+ protected String methodDesc;
+
+ /** Whether the visited method is a constructor. */
+ private final boolean isConstructor;
+
+ /**
+ * Whether the super class constructor has been called (if the visited method is a constructor),
+ * at the current instruction. There can be multiple call sites to the super constructor (e.g. for
+ * Java code such as {@code super(expr ? value1 : value2);}), in different branches. When scanning
+ * the bytecode linearly, we can move from one branch where the super constructor has been called
+ * to another where it has not been called yet. Therefore, this value can change from false to
+ * true, and vice-versa.
+ */
+ private boolean superClassConstructorCalled;
+
+ /**
+ * The values on the current execution stack frame (long and double are represented by two
+ * elements). Each value is either {@link #UNINITIALIZED_THIS} (for the uninitialized this value),
+ * or {@link #OTHER} (for any other value). This field is only maintained for constructors, in
+ * branches where the super class constructor has not been called yet.
+ */
+ private List<Object> stackFrame;
+
+ /**
+ * The stack map frames corresponding to the labels of the forward jumps made *before* the super
+ * class constructor has been called (note that the Java Virtual Machine forbids backward jumps
+ * before the super class constructor is called). Note that by definition (cf. the 'before'), when
+ * we reach a label from this map, {@link #superClassConstructorCalled} must be reset to false.
+ * This field is only maintained for constructors.
+ */
+ private Map<Label, List<Object>> forwardJumpStackFrames;
+
+ /**
+ * Constructs a new {@link AdviceAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type Type}).
+ */
+ protected AdviceAdapter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor) {
+ super(api, methodVisitor, access, name, descriptor);
+ methodAccess = access;
+ methodDesc = descriptor;
+ isConstructor = "<init>".equals(name);
+ }
+
+ @Override
+ public void visitCode() {
+ super.visitCode();
+ if (isConstructor) {
+ stackFrame = new ArrayList<>();
+ forwardJumpStackFrames = new HashMap<>();
+ } else {
+ onMethodEnter();
+ }
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ super.visitLabel(label);
+ if (isConstructor && forwardJumpStackFrames != null) {
+ List<Object> labelStackFrame = forwardJumpStackFrames.get(label);
+ if (labelStackFrame != null) {
+ stackFrame = labelStackFrame;
+ superClassConstructorCalled = false;
+ forwardJumpStackFrames.remove(label);
+ }
+ }
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ if (isConstructor && !superClassConstructorCalled) {
+ int stackSize;
+ switch (opcode) {
+ case IRETURN:
+ case FRETURN:
+ case ARETURN:
+ case LRETURN:
+ case DRETURN:
+ throw new IllegalArgumentException("Invalid return in constructor");
+ case RETURN: // empty stack
+ onMethodExit(opcode);
+ endConstructorBasicBlockWithoutSuccessor();
+ break;
+ case ATHROW: // 1 before n/a after
+ popValue();
+ onMethodExit(opcode);
+ endConstructorBasicBlockWithoutSuccessor();
+ break;
+ case NOP:
+ case LALOAD: // remove 2 add 2
+ case DALOAD: // remove 2 add 2
+ case LNEG:
+ case DNEG:
+ case FNEG:
+ case INEG:
+ case L2D:
+ case D2L:
+ case F2I:
+ case I2B:
+ case I2C:
+ case I2S:
+ case I2F:
+ case ARRAYLENGTH:
+ break;
+ case ACONST_NULL:
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ case F2L: // 1 before 2 after
+ case F2D:
+ case I2L:
+ case I2D:
+ pushValue(OTHER);
+ break;
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ pushValue(OTHER);
+ pushValue(OTHER);
+ break;
+ case IALOAD: // remove 2 add 1
+ case FALOAD: // remove 2 add 1
+ case AALOAD: // remove 2 add 1
+ case BALOAD: // remove 2 add 1
+ case CALOAD: // remove 2 add 1
+ case SALOAD: // remove 2 add 1
+ case POP:
+ case IADD:
+ case FADD:
+ case ISUB:
+ case LSHL: // 3 before 2 after
+ case LSHR: // 3 before 2 after
+ case LUSHR: // 3 before 2 after
+ case L2I: // 2 before 1 after
+ case L2F: // 2 before 1 after
+ case D2I: // 2 before 1 after
+ case D2F: // 2 before 1 after
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ case FCMPL: // 2 before 1 after
+ case FCMPG: // 2 before 1 after
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ case MONITORENTER:
+ case MONITOREXIT:
+ popValue();
+ break;
+ case POP2:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LADD:
+ case LAND:
+ case LOR:
+ case LXOR:
+ case DADD:
+ case DMUL:
+ case DSUB:
+ case DDIV:
+ case DREM:
+ popValue();
+ popValue();
+ break;
+ case IASTORE:
+ case FASTORE:
+ case AASTORE:
+ case BASTORE:
+ case CASTORE:
+ case SASTORE:
+ case LCMP: // 4 before 1 after
+ case DCMPL:
+ case DCMPG:
+ popValue();
+ popValue();
+ popValue();
+ break;
+ case LASTORE:
+ case DASTORE:
+ popValue();
+ popValue();
+ popValue();
+ popValue();
+ break;
+ case DUP:
+ pushValue(peekValue());
+ break;
+ case DUP_X1:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ break;
+ case DUP_X2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2_X1:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 3, stackFrame.get(stackSize - 1));
+ break;
+ case DUP2_X2:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 4, stackFrame.get(stackSize - 1));
+ stackFrame.add(stackSize - 4, stackFrame.get(stackSize - 1));
+ break;
+ case SWAP:
+ stackSize = stackFrame.size();
+ stackFrame.add(stackSize - 2, stackFrame.get(stackSize - 1));
+ stackFrame.remove(stackSize);
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
+ } else {
+ switch (opcode) {
+ case RETURN:
+ case IRETURN:
+ case FRETURN:
+ case ARETURN:
+ case LRETURN:
+ case DRETURN:
+ case ATHROW:
+ onMethodExit(opcode);
+ break;
+ default:
+ break;
+ }
+ }
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ super.visitVarInsn(opcode, varIndex);
+ if (isConstructor && !superClassConstructorCalled) {
+ switch (opcode) {
+ case ILOAD:
+ case FLOAD:
+ pushValue(OTHER);
+ break;
+ case LLOAD:
+ case DLOAD:
+ pushValue(OTHER);
+ pushValue(OTHER);
+ break;
+ case ALOAD:
+ pushValue(varIndex == 0 ? UNINITIALIZED_THIS : OTHER);
+ break;
+ case ASTORE:
+ case ISTORE:
+ case FSTORE:
+ popValue();
+ break;
+ case LSTORE:
+ case DSTORE:
+ popValue();
+ popValue();
+ break;
+ case RET:
+ endConstructorBasicBlockWithoutSuccessor();
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
+ }
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ if (isConstructor && !superClassConstructorCalled) {
+ char firstDescriptorChar = descriptor.charAt(0);
+ boolean longOrDouble = firstDescriptorChar == 'J' || firstDescriptorChar == 'D';
+ switch (opcode) {
+ case GETSTATIC:
+ pushValue(OTHER);
+ if (longOrDouble) {
+ pushValue(OTHER);
+ }
+ break;
+ case PUTSTATIC:
+ popValue();
+ if (longOrDouble) {
+ popValue();
+ }
+ break;
+ case PUTFIELD:
+ popValue();
+ popValue();
+ if (longOrDouble) {
+ popValue();
+ }
+ break;
+ case GETFIELD:
+ if (longOrDouble) {
+ pushValue(OTHER);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(INVALID_OPCODE + opcode);
+ }
+ }
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ super.visitIntInsn(opcode, operand);
+ if (isConstructor && !superClassConstructorCalled && opcode != NEWARRAY) {
+ pushValue(OTHER);
+ }
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ super.visitLdcInsn(value);
+ if (isConstructor && !superClassConstructorCalled) {
+ pushValue(OTHER);
+ if (value instanceof Double
+ || value instanceof Long
+ || (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
+ pushValue(OTHER);
+ }
+ }
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ if (isConstructor && !superClassConstructorCalled) {
+ for (int i = 0; i < numDimensions; i++) {
+ popValue();
+ }
+ pushValue(OTHER);
+ }
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ super.visitTypeInsn(opcode, type);
+ // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack.
+ if (isConstructor && !superClassConstructorCalled && opcode == NEW) {
+ pushValue(OTHER);
+ }
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ doVisitMethodInsn(opcode, name, descriptor);
+ }
+
+ private void doVisitMethodInsn(final int opcode, final String name, final String descriptor) {
+ if (isConstructor && !superClassConstructorCalled) {
+ for (Type argumentType : Type.getArgumentTypes(descriptor)) {
+ popValue();
+ if (argumentType.getSize() == 2) {
+ popValue();
+ }
+ }
+ switch (opcode) {
+ case INVOKEINTERFACE:
+ case INVOKEVIRTUAL:
+ popValue();
+ break;
+ case INVOKESPECIAL:
+ Object value = popValue();
+ if (value == UNINITIALIZED_THIS
+ && !superClassConstructorCalled
+ && name.equals("<init>")) {
+ superClassConstructorCalled = true;
+ onMethodEnter();
+ }
+ break;
+ default:
+ break;
+ }
+
+ Type returnType = Type.getReturnType(descriptor);
+ if (returnType != Type.VOID_TYPE) {
+ pushValue(OTHER);
+ if (returnType.getSize() == 2) {
+ pushValue(OTHER);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ doVisitMethodInsn(Opcodes.INVOKEDYNAMIC, name, descriptor);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ super.visitJumpInsn(opcode, label);
+ if (isConstructor && !superClassConstructorCalled) {
+ switch (opcode) {
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case IFNULL:
+ case IFNONNULL:
+ popValue();
+ break;
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ popValue();
+ popValue();
+ break;
+ case JSR:
+ pushValue(OTHER);
+ break;
+ case GOTO:
+ endConstructorBasicBlockWithoutSuccessor();
+ break;
+ default:
+ break;
+ }
+ addForwardJump(label);
+ }
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ if (isConstructor && !superClassConstructorCalled) {
+ popValue();
+ addForwardJumps(dflt, labels);
+ endConstructorBasicBlockWithoutSuccessor();
+ }
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ if (isConstructor && !superClassConstructorCalled) {
+ popValue();
+ addForwardJumps(dflt, labels);
+ endConstructorBasicBlockWithoutSuccessor();
+ }
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ super.visitTryCatchBlock(start, end, handler, type);
+ // By definition of 'forwardJumpStackFrames', 'handler' should be pushed only if there is an
+ // instruction between 'start' and 'end' at which the super class constructor is not yet
+ // called. Unfortunately, try catch blocks must be visited before their labels, so we have no
+ // way to know this at this point. Instead, we suppose that the super class constructor has not
+ // been called at the start of *any* exception handler. If this is wrong, normally there should
+ // not be a second super class constructor call in the exception handler (an object can't be
+ // initialized twice), so this is not issue (in the sense that there is no risk to emit a wrong
+ // 'onMethodEnter').
+ if (isConstructor && !forwardJumpStackFrames.containsKey(handler)) {
+ List<Object> handlerStackFrame = new ArrayList<>();
+ handlerStackFrame.add(OTHER);
+ forwardJumpStackFrames.put(handler, handlerStackFrame);
+ }
+ }
+
+ private void addForwardJumps(final Label dflt, final Label[] labels) {
+ addForwardJump(dflt);
+ for (Label label : labels) {
+ addForwardJump(label);
+ }
+ }
+
+ private void addForwardJump(final Label label) {
+ if (forwardJumpStackFrames.containsKey(label)) {
+ return;
+ }
+ forwardJumpStackFrames.put(label, new ArrayList<>(stackFrame));
+ }
+
+ private void endConstructorBasicBlockWithoutSuccessor() {
+ // The next instruction is not reachable from this instruction. If it is dead code, we
+ // should not try to simulate stack operations, and there is no need to insert advices
+ // here. If it is reachable with a backward jump, the only possible case is that the super
+ // class constructor has already been called (backward jumps are forbidden before it is
+ // called). If it is reachable with a forward jump, there are two sub-cases. Either the
+ // super class constructor has already been called when reaching the next instruction, or
+ // it has not been called. But in this case there must be a forwardJumpStackFrames entry
+ // for a Label designating the next instruction, and superClassConstructorCalled will be
+ // reset to false there. We can therefore always reset this field to true here.
+ superClassConstructorCalled = true;
+ }
+
+ private Object popValue() {
+ return stackFrame.remove(stackFrame.size() - 1);
+ }
+
+ private Object peekValue() {
+ return stackFrame.get(stackFrame.size() - 1);
+ }
+
+ private void pushValue(final Object value) {
+ stackFrame.add(value);
+ }
+
+ /**
+ * Generates the "before" advice for the visited method. The default implementation of this method
+ * does nothing. Subclasses can use or change all the local variables, but should not change state
+ * of the stack. This method is called at the beginning of the method or after super class
+ * constructor has been called (in constructors).
+ */
+ protected void onMethodEnter() {}
+
+ /**
+ * Generates the "after" advice for the visited method. The default implementation of this method
+ * does nothing. Subclasses can use or change all the local variables, but should not change state
+ * of the stack. This method is called at the end of the method, just before return and athrow
+ * instructions. The top element on the stack contains the return value or the exception instance.
+ * For example:
+ *
+ * <pre>
+ * public void onMethodExit(final int opcode) {
+ * if (opcode == RETURN) {
+ * visitInsn(ACONST_NULL);
+ * } else if (opcode == ARETURN || opcode == ATHROW) {
+ * dup();
+ * } else {
+ * if (opcode == LRETURN || opcode == DRETURN) {
+ * dup2();
+ * } else {
+ * dup();
+ * }
+ * box(Type.getReturnType(this.methodDesc));
+ * }
+ * visitIntInsn(SIPUSH, opcode);
+ * visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
+ * }
+ *
+ * // An actual call back method.
+ * public static void onExit(final Object exitValue, final int opcode) {
+ * ...
+ * }
+ * </pre>
+ *
+ * @param opcode one of {@link Opcodes#RETURN}, {@link Opcodes#IRETURN}, {@link Opcodes#FRETURN},
+ * {@link Opcodes#ARETURN}, {@link Opcodes#LRETURN}, {@link Opcodes#DRETURN} or {@link
+ * Opcodes#ATHROW}.
+ */
+ protected void onMethodExit(final int opcode) {}
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java
new file mode 100644
index 00000000..c31533ec
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java
@@ -0,0 +1,910 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link MethodVisitor} that keeps track of stack map frame changes between {@link
+ * #visitFrame(int, int, Object[], int, Object[])} calls. This adapter must be used with the {@link
+ * org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>X</i> instruction delegates to
+ * the next visitor in the chain, if any, and then simulates the effect of this instruction on the
+ * stack map frame, represented by {@link #locals} and {@link #stack}. The next visitor in the chain
+ * can get the state of the stack map frame <i>before</i> each instruction by reading the value of
+ * these fields in its visit<i>X</i> methods (this requires a reference to the AnalyzerAdapter that
+ * is before it in the chain). If this adapter is used with a class that does not contain stack map
+ * table attributes (i.e., pre Java 6 classes) then this adapter may not be able to compute the
+ * stack map frame for each instruction. In this case no exception is thrown but the {@link #locals}
+ * and {@link #stack} fields will be null for these instructions.
+ *
+ * @author Eric Bruneton
+ */
+public class AnalyzerAdapter extends MethodVisitor {
+
+ /**
+ * The local variable slots for the current execution frame. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and
+ * double are represented by two elements, the second one being TOP). Reference types are
+ * represented by String objects (representing internal names, see {@link
+ * Type#getInternalName()}), and uninitialized types by Label objects (this label designates the
+ * NEW instruction that created this uninitialized value). This field is {@literal null} for
+ * unreachable instructions.
+ */
+ public List<Object> locals;
+
+ /**
+ * The operand stack slots for the current execution frame. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and
+ * double are represented by two elements, the second one being TOP). Reference types are
+ * represented by String objects (representing internal names, see {@link
+ * Type#getInternalName()}), and uninitialized types by Label objects (this label designates the
+ * NEW instruction that created this uninitialized value). This field is {@literal null} for
+ * unreachable instructions.
+ */
+ public List<Object> stack;
+
+ /** The labels that designate the next instruction to be visited. May be {@literal null}. */
+ private List<Label> labels;
+
+ /**
+ * The uninitialized types in the current execution frame. This map associates internal names to
+ * Label objects (see {@link Type#getInternalName()}). Each label designates a NEW instruction
+ * that created the currently uninitialized types, and the associated internal name represents the
+ * NEW operand, i.e. the final, initialized type value.
+ */
+ public Map<Object, Object> uninitializedTypes;
+
+ /** The maximum stack size of this method. */
+ private int maxStack;
+
+ /** The maximum number of local variables of this method. */
+ private int maxLocals;
+
+ /** The owner's class name. */
+ private String owner;
+
+ /**
+ * Constructs a new {@link AnalyzerAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #AnalyzerAdapter(int, String, int, String, String,
+ * MethodVisitor)} version.
+ *
+ * @param owner the owner's class name.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter delegates calls. May be {@literal
+ * null}.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public AnalyzerAdapter(
+ final String owner,
+ final int access,
+ final String name,
+ final String descriptor,
+ final MethodVisitor methodVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, owner, access, name, descriptor, methodVisitor);
+ if (getClass() != AnalyzerAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link AnalyzerAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param owner the owner's class name.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter delegates calls. May be {@literal
+ * null}.
+ */
+ protected AnalyzerAdapter(
+ final int api,
+ final String owner,
+ final int access,
+ final String name,
+ final String descriptor,
+ final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ this.owner = owner;
+ locals = new ArrayList<>();
+ stack = new ArrayList<>();
+ uninitializedTypes = new HashMap<>();
+
+ if ((access & Opcodes.ACC_STATIC) == 0) {
+ if ("<init>".equals(name)) {
+ locals.add(Opcodes.UNINITIALIZED_THIS);
+ } else {
+ locals.add(owner);
+ }
+ }
+ for (Type argumentType : Type.getArgumentTypes(descriptor)) {
+ switch (argumentType.getSort()) {
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ locals.add(Opcodes.INTEGER);
+ break;
+ case Type.FLOAT:
+ locals.add(Opcodes.FLOAT);
+ break;
+ case Type.LONG:
+ locals.add(Opcodes.LONG);
+ locals.add(Opcodes.TOP);
+ break;
+ case Type.DOUBLE:
+ locals.add(Opcodes.DOUBLE);
+ locals.add(Opcodes.TOP);
+ break;
+ case Type.ARRAY:
+ locals.add(argumentType.getDescriptor());
+ break;
+ case Type.OBJECT:
+ locals.add(argumentType.getInternalName());
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+ maxLocals = locals.size();
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ if (type != Opcodes.F_NEW) { // Uncompressed frame.
+ throw new IllegalArgumentException(
+ "AnalyzerAdapter only accepts expanded frames (see ClassReader.EXPAND_FRAMES)");
+ }
+
+ super.visitFrame(type, numLocal, local, numStack, stack);
+
+ if (this.locals != null) {
+ this.locals.clear();
+ this.stack.clear();
+ } else {
+ this.locals = new ArrayList<>();
+ this.stack = new ArrayList<>();
+ }
+ visitFrameTypes(numLocal, local, this.locals);
+ visitFrameTypes(numStack, stack, this.stack);
+ maxLocals = Math.max(maxLocals, this.locals.size());
+ maxStack = Math.max(maxStack, this.stack.size());
+ }
+
+ private static void visitFrameTypes(
+ final int numTypes, final Object[] frameTypes, final List<Object> result) {
+ for (int i = 0; i < numTypes; ++i) {
+ Object frameType = frameTypes[i];
+ result.add(frameType);
+ if (frameType == Opcodes.LONG || frameType == Opcodes.DOUBLE) {
+ result.add(Opcodes.TOP);
+ }
+ }
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ super.visitInsn(opcode);
+ execute(opcode, 0, null);
+ if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
+ this.locals = null;
+ this.stack = null;
+ }
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ super.visitIntInsn(opcode, operand);
+ execute(opcode, operand, null);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ super.visitVarInsn(opcode, varIndex);
+ boolean isLongOrDouble =
+ opcode == Opcodes.LLOAD
+ || opcode == Opcodes.DLOAD
+ || opcode == Opcodes.LSTORE
+ || opcode == Opcodes.DSTORE;
+ maxLocals = Math.max(maxLocals, varIndex + (isLongOrDouble ? 2 : 1));
+ execute(opcode, varIndex, null);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ if (opcode == Opcodes.NEW) {
+ if (labels == null) {
+ Label label = new Label();
+ labels = new ArrayList<>(3);
+ labels.add(label);
+ if (mv != null) {
+ mv.visitLabel(label);
+ }
+ }
+ for (Label label : labels) {
+ uninitializedTypes.put(label, type);
+ }
+ }
+ super.visitTypeInsn(opcode, type);
+ execute(opcode, 0, type);
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ execute(opcode, 0, descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ if (this.locals == null) {
+ labels = null;
+ return;
+ }
+ pop(descriptor);
+ if (opcode != Opcodes.INVOKESTATIC) {
+ Object value = pop();
+ if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>")) {
+ Object initializedValue;
+ if (value == Opcodes.UNINITIALIZED_THIS) {
+ initializedValue = this.owner;
+ } else {
+ initializedValue = uninitializedTypes.get(value);
+ }
+ for (int i = 0; i < locals.size(); ++i) {
+ if (locals.get(i) == value) {
+ locals.set(i, initializedValue);
+ }
+ }
+ for (int i = 0; i < stack.size(); ++i) {
+ if (stack.get(i) == value) {
+ stack.set(i, initializedValue);
+ }
+ }
+ }
+ }
+ pushDescriptor(descriptor);
+ labels = null;
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ if (this.locals == null) {
+ labels = null;
+ return;
+ }
+ pop(descriptor);
+ pushDescriptor(descriptor);
+ labels = null;
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ super.visitJumpInsn(opcode, label);
+ execute(opcode, 0, null);
+ if (opcode == Opcodes.GOTO) {
+ this.locals = null;
+ this.stack = null;
+ }
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ super.visitLabel(label);
+ if (labels == null) {
+ labels = new ArrayList<>(3);
+ }
+ labels.add(label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ super.visitLdcInsn(value);
+ if (this.locals == null) {
+ labels = null;
+ return;
+ }
+ if (value instanceof Integer) {
+ push(Opcodes.INTEGER);
+ } else if (value instanceof Long) {
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ } else if (value instanceof Float) {
+ push(Opcodes.FLOAT);
+ } else if (value instanceof Double) {
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ } else if (value instanceof String) {
+ push("java/lang/String");
+ } else if (value instanceof Type) {
+ int sort = ((Type) value).getSort();
+ if (sort == Type.OBJECT || sort == Type.ARRAY) {
+ push("java/lang/Class");
+ } else if (sort == Type.METHOD) {
+ push("java/lang/invoke/MethodType");
+ } else {
+ throw new IllegalArgumentException();
+ }
+ } else if (value instanceof Handle) {
+ push("java/lang/invoke/MethodHandle");
+ } else if (value instanceof ConstantDynamic) {
+ pushDescriptor(((ConstantDynamic) value).getDescriptor());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ labels = null;
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ super.visitIincInsn(varIndex, increment);
+ maxLocals = Math.max(maxLocals, varIndex + 1);
+ execute(Opcodes.IINC, varIndex, null);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ execute(Opcodes.TABLESWITCH, 0, null);
+ this.locals = null;
+ this.stack = null;
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ execute(Opcodes.LOOKUPSWITCH, 0, null);
+ this.locals = null;
+ this.stack = null;
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ execute(Opcodes.MULTIANEWARRAY, numDimensions, descriptor);
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ char firstDescriptorChar = descriptor.charAt(0);
+ maxLocals =
+ Math.max(
+ maxLocals, index + (firstDescriptorChar == 'J' || firstDescriptorChar == 'D' ? 2 : 1));
+ super.visitLocalVariable(name, descriptor, signature, start, end, index);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ if (mv != null) {
+ this.maxStack = Math.max(this.maxStack, maxStack);
+ this.maxLocals = Math.max(this.maxLocals, maxLocals);
+ mv.visitMaxs(this.maxStack, this.maxLocals);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ private Object get(final int local) {
+ maxLocals = Math.max(maxLocals, local + 1);
+ return local < locals.size() ? locals.get(local) : Opcodes.TOP;
+ }
+
+ private void set(final int local, final Object type) {
+ maxLocals = Math.max(maxLocals, local + 1);
+ while (local >= locals.size()) {
+ locals.add(Opcodes.TOP);
+ }
+ locals.set(local, type);
+ }
+
+ private void push(final Object type) {
+ stack.add(type);
+ maxStack = Math.max(maxStack, stack.size());
+ }
+
+ private void pushDescriptor(final String fieldOrMethodDescriptor) {
+ String descriptor =
+ fieldOrMethodDescriptor.charAt(0) == '('
+ ? Type.getReturnType(fieldOrMethodDescriptor).getDescriptor()
+ : fieldOrMethodDescriptor;
+ switch (descriptor.charAt(0)) {
+ case 'V':
+ return;
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ push(Opcodes.INTEGER);
+ return;
+ case 'F':
+ push(Opcodes.FLOAT);
+ return;
+ case 'J':
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ return;
+ case 'D':
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ return;
+ case '[':
+ push(descriptor);
+ break;
+ case 'L':
+ push(descriptor.substring(1, descriptor.length() - 1));
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ private Object pop() {
+ return stack.remove(stack.size() - 1);
+ }
+
+ private void pop(final int numSlots) {
+ int size = stack.size();
+ int end = size - numSlots;
+ for (int i = size - 1; i >= end; --i) {
+ stack.remove(i);
+ }
+ }
+
+ private void pop(final String descriptor) {
+ char firstDescriptorChar = descriptor.charAt(0);
+ if (firstDescriptorChar == '(') {
+ int numSlots = 0;
+ Type[] types = Type.getArgumentTypes(descriptor);
+ for (Type type : types) {
+ numSlots += type.getSize();
+ }
+ pop(numSlots);
+ } else if (firstDescriptorChar == 'J' || firstDescriptorChar == 'D') {
+ pop(2);
+ } else {
+ pop(1);
+ }
+ }
+
+ private void execute(final int opcode, final int intArg, final String stringArg) {
+ if (opcode == Opcodes.JSR || opcode == Opcodes.RET) {
+ throw new IllegalArgumentException("JSR/RET are not supported");
+ }
+ if (this.locals == null) {
+ labels = null;
+ return;
+ }
+ Object value1;
+ Object value2;
+ Object value3;
+ Object t4;
+ switch (opcode) {
+ case Opcodes.NOP:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.GOTO:
+ case Opcodes.RETURN:
+ break;
+ case Opcodes.ACONST_NULL:
+ push(Opcodes.NULL);
+ break;
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ push(Opcodes.INTEGER);
+ break;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ push(Opcodes.FLOAT);
+ break;
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.ILOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.ALOAD:
+ push(get(intArg));
+ break;
+ case Opcodes.LLOAD:
+ case Opcodes.DLOAD:
+ push(get(intArg));
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.LALOAD:
+ case Opcodes.D2L:
+ pop(2);
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.DALOAD:
+ case Opcodes.L2D:
+ pop(2);
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.AALOAD:
+ pop(1);
+ value1 = pop();
+ if (value1 instanceof String) {
+ pushDescriptor(((String) value1).substring(1));
+ } else if (value1 == Opcodes.NULL) {
+ push(value1);
+ } else {
+ push("java/lang/Object");
+ }
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.ASTORE:
+ value1 = pop();
+ set(intArg, value1);
+ if (intArg > 0) {
+ value2 = get(intArg - 1);
+ if (value2 == Opcodes.LONG || value2 == Opcodes.DOUBLE) {
+ set(intArg - 1, Opcodes.TOP);
+ }
+ }
+ break;
+ case Opcodes.LSTORE:
+ case Opcodes.DSTORE:
+ pop(1);
+ value1 = pop();
+ set(intArg, value1);
+ set(intArg + 1, Opcodes.TOP);
+ if (intArg > 0) {
+ value2 = get(intArg - 1);
+ if (value2 == Opcodes.LONG || value2 == Opcodes.DOUBLE) {
+ set(intArg - 1, Opcodes.TOP);
+ }
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.AASTORE:
+ pop(3);
+ break;
+ case Opcodes.LASTORE:
+ case Opcodes.DASTORE:
+ pop(4);
+ break;
+ case Opcodes.POP:
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ pop(1);
+ break;
+ case Opcodes.POP2:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.LRETURN:
+ case Opcodes.DRETURN:
+ pop(2);
+ break;
+ case Opcodes.DUP:
+ value1 = pop();
+ push(value1);
+ push(value1);
+ break;
+ case Opcodes.DUP_X1:
+ value1 = pop();
+ value2 = pop();
+ push(value1);
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP_X2:
+ value1 = pop();
+ value2 = pop();
+ value3 = pop();
+ push(value1);
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP2:
+ value1 = pop();
+ value2 = pop();
+ push(value2);
+ push(value1);
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP2_X1:
+ value1 = pop();
+ value2 = pop();
+ value3 = pop();
+ push(value2);
+ push(value1);
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP2_X2:
+ value1 = pop();
+ value2 = pop();
+ value3 = pop();
+ t4 = pop();
+ push(value2);
+ push(value1);
+ push(t4);
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.SWAP:
+ value1 = pop();
+ value2 = pop();
+ push(value1);
+ push(value2);
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IADD:
+ case Opcodes.ISUB:
+ case Opcodes.IMUL:
+ case Opcodes.IDIV:
+ case Opcodes.IREM:
+ case Opcodes.IAND:
+ case Opcodes.IOR:
+ case Opcodes.IXOR:
+ case Opcodes.ISHL:
+ case Opcodes.ISHR:
+ case Opcodes.IUSHR:
+ case Opcodes.L2I:
+ case Opcodes.D2I:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ pop(2);
+ push(Opcodes.INTEGER);
+ break;
+ case Opcodes.LADD:
+ case Opcodes.LSUB:
+ case Opcodes.LMUL:
+ case Opcodes.LDIV:
+ case Opcodes.LREM:
+ case Opcodes.LAND:
+ case Opcodes.LOR:
+ case Opcodes.LXOR:
+ pop(4);
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.FALOAD:
+ case Opcodes.FADD:
+ case Opcodes.FSUB:
+ case Opcodes.FMUL:
+ case Opcodes.FDIV:
+ case Opcodes.FREM:
+ case Opcodes.L2F:
+ case Opcodes.D2F:
+ pop(2);
+ push(Opcodes.FLOAT);
+ break;
+ case Opcodes.DADD:
+ case Opcodes.DSUB:
+ case Opcodes.DMUL:
+ case Opcodes.DDIV:
+ case Opcodes.DREM:
+ pop(4);
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.LSHL:
+ case Opcodes.LSHR:
+ case Opcodes.LUSHR:
+ pop(3);
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.IINC:
+ set(intArg, Opcodes.INTEGER);
+ break;
+ case Opcodes.I2L:
+ case Opcodes.F2L:
+ pop(1);
+ push(Opcodes.LONG);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.I2F:
+ pop(1);
+ push(Opcodes.FLOAT);
+ break;
+ case Opcodes.I2D:
+ case Opcodes.F2D:
+ pop(1);
+ push(Opcodes.DOUBLE);
+ push(Opcodes.TOP);
+ break;
+ case Opcodes.F2I:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.INSTANCEOF:
+ pop(1);
+ push(Opcodes.INTEGER);
+ break;
+ case Opcodes.LCMP:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ pop(4);
+ push(Opcodes.INTEGER);
+ break;
+ case Opcodes.GETSTATIC:
+ pushDescriptor(stringArg);
+ break;
+ case Opcodes.PUTSTATIC:
+ pop(stringArg);
+ break;
+ case Opcodes.GETFIELD:
+ pop(1);
+ pushDescriptor(stringArg);
+ break;
+ case Opcodes.PUTFIELD:
+ pop(stringArg);
+ pop();
+ break;
+ case Opcodes.NEW:
+ push(labels.get(0));
+ break;
+ case Opcodes.NEWARRAY:
+ pop();
+ switch (intArg) {
+ case Opcodes.T_BOOLEAN:
+ pushDescriptor("[Z");
+ break;
+ case Opcodes.T_CHAR:
+ pushDescriptor("[C");
+ break;
+ case Opcodes.T_BYTE:
+ pushDescriptor("[B");
+ break;
+ case Opcodes.T_SHORT:
+ pushDescriptor("[S");
+ break;
+ case Opcodes.T_INT:
+ pushDescriptor("[I");
+ break;
+ case Opcodes.T_FLOAT:
+ pushDescriptor("[F");
+ break;
+ case Opcodes.T_DOUBLE:
+ pushDescriptor("[D");
+ break;
+ case Opcodes.T_LONG:
+ pushDescriptor("[J");
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid array type " + intArg);
+ }
+ break;
+ case Opcodes.ANEWARRAY:
+ pop();
+ pushDescriptor("[" + Type.getObjectType(stringArg));
+ break;
+ case Opcodes.CHECKCAST:
+ pop();
+ pushDescriptor(Type.getObjectType(stringArg).getDescriptor());
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ pop(intArg);
+ pushDescriptor(stringArg);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid opcode " + opcode);
+ }
+ labels = null;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java
new file mode 100644
index 00000000..3eeaf0f6
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java
@@ -0,0 +1,210 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * An {@link AnnotationVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Eugene Kuleshov
+ */
+public class AnnotationRemapper extends AnnotationVisitor {
+
+ /**
+ * The descriptor of the visited annotation. May be {@literal null}, for instance for
+ * AnnotationDefault.
+ */
+ protected final String descriptor;
+
+ /** The remapper used to remap the types in the visited annotation. */
+ protected final Remapper remapper;
+
+ /**
+ * Constructs a new {@link AnnotationRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #AnnotationRemapper(int,AnnotationVisitor,Remapper)} version.
+ *
+ * @param annotationVisitor the annotation visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited annotation.
+ * @deprecated use {@link #AnnotationRemapper(String, AnnotationVisitor, Remapper)} instead.
+ */
+ @Deprecated
+ public AnnotationRemapper(final AnnotationVisitor annotationVisitor, final Remapper remapper) {
+ this(/* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link AnnotationRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #AnnotationRemapper(int,String,AnnotationVisitor,Remapper)}
+ * version.
+ *
+ * @param descriptor the descriptor of the visited annotation. May be {@literal null}.
+ * @param annotationVisitor the annotation visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited annotation.
+ */
+ public AnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, descriptor, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link AnnotationRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param annotationVisitor the annotation visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited annotation.
+ * @deprecated use {@link #AnnotationRemapper(int, String, AnnotationVisitor, Remapper)} instead.
+ */
+ @Deprecated
+ protected AnnotationRemapper(
+ final int api, final AnnotationVisitor annotationVisitor, final Remapper remapper) {
+ this(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link AnnotationRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param descriptor the descriptor of the visited annotation. May be {@literal null}.
+ * @param annotationVisitor the annotation visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited annotation.
+ */
+ protected AnnotationRemapper(
+ final int api,
+ final String descriptor,
+ final AnnotationVisitor annotationVisitor,
+ final Remapper remapper) {
+ super(api, annotationVisitor);
+ this.descriptor = descriptor;
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visit(final String name, final Object value) {
+ super.visit(mapAnnotationAttributeName(name), remapper.mapValue(value));
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ super.visitEnum(mapAnnotationAttributeName(name), remapper.mapDesc(descriptor), value);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ AnnotationVisitor annotationVisitor =
+ super.visitAnnotation(mapAnnotationAttributeName(name), remapper.mapDesc(descriptor));
+ if (annotationVisitor == null) {
+ return null;
+ } else {
+ return annotationVisitor == av
+ ? this
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ AnnotationVisitor annotationVisitor = super.visitArray(mapAnnotationAttributeName(name));
+ if (annotationVisitor == null) {
+ return null;
+ } else {
+ return annotationVisitor == av
+ ? this
+ : createAnnotationRemapper(/* descriptor = */ null, annotationVisitor);
+ }
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead.
+ */
+ @Deprecated
+ protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param descriptor the descriptor of the visited annotation.
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected AnnotationVisitor createAnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper)
+ .orDeprecatedValue(createAnnotationRemapper(annotationVisitor));
+ }
+
+ /**
+ * Returns either this object, or the given one. If the given object is equal to the object
+ * returned by the default implementation of the deprecated createAnnotationRemapper method,
+ * meaning that this method has not been overridden (or only in minor ways, for instance to add
+ * logging), then we can return this object instead, supposed to have been created by the new
+ * createAnnotationRemapper method. Otherwise we must return the given object.
+ *
+ * @param deprecatedAnnotationVisitor the result of a call to the deprecated
+ * createAnnotationRemapper method.
+ * @return either this object, or the given one.
+ */
+ final AnnotationVisitor orDeprecatedValue(final AnnotationVisitor deprecatedAnnotationVisitor) {
+ if (deprecatedAnnotationVisitor.getClass() == getClass()) {
+ AnnotationRemapper deprecatedAnnotationRemapper =
+ (AnnotationRemapper) deprecatedAnnotationVisitor;
+ if (deprecatedAnnotationRemapper.api == api
+ && deprecatedAnnotationRemapper.av == av
+ && deprecatedAnnotationRemapper.remapper == remapper) {
+ return this;
+ }
+ }
+ return deprecatedAnnotationVisitor;
+ }
+
+ /**
+ * Maps an annotation attribute name with the remapper. Returns the original name unchanged if the
+ * descriptor of the annotation is {@literal null}.
+ *
+ * @param name the name of the annotation attribute.
+ * @return the new name of the annotation attribute.
+ */
+ private String mapAnnotationAttributeName(final String name) {
+ if (descriptor == null) {
+ return name;
+ }
+ return remapper.mapAnnotationAttributeName(descriptor, name);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java
new file mode 100644
index 00000000..4ce62395
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java
@@ -0,0 +1,300 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link ClassVisitor} that remaps types with a {@link Remapper}.
+ *
+ * <p><i>This visitor has several limitations</i>. A non-exhaustive list is the following:
+ *
+ * <ul>
+ * <li>it cannot remap type names in dynamically computed strings (remapping of type names in
+ * static values is supported).
+ * <li>it cannot remap values derived from type names at compile time, such as
+ * <ul>
+ * <li>type name hashcodes used by some Java compilers to implement the string switch
+ * statement.
+ * <li>some compound strings used by some Java compilers to implement lambda
+ * deserialization.
+ * </ul>
+ * </ul>
+ *
+ * @author Eugene Kuleshov
+ */
+public class ClassRemapper extends ClassVisitor {
+
+ /** The remapper used to remap the types in the visited class. */
+ protected final Remapper remapper;
+
+ /** The internal name of the visited class. */
+ protected String className;
+
+ /**
+ * Constructs a new {@link ClassRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #ClassRemapper(int,ClassVisitor,Remapper)} version.
+ *
+ * @param classVisitor the class visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited class.
+ */
+ public ClassRemapper(final ClassVisitor classVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, classVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link ClassRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param classVisitor the class visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited class.
+ */
+ protected ClassRemapper(final int api, final ClassVisitor classVisitor, final Remapper remapper) {
+ super(api, classVisitor);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ this.className = name;
+ super.visit(
+ version,
+ access,
+ remapper.mapType(name),
+ remapper.mapSignature(signature, false),
+ remapper.mapType(superName),
+ interfaces == null ? null : remapper.mapTypes(interfaces));
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int flags, final String version) {
+ ModuleVisitor moduleVisitor = super.visitModule(remapper.mapModuleName(name), flags, version);
+ return moduleVisitor == null ? null : createModuleRemapper(moduleVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitAnnotation(remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ if (attribute instanceof ModuleHashesAttribute) {
+ ModuleHashesAttribute moduleHashesAttribute = (ModuleHashesAttribute) attribute;
+ List<String> modules = moduleHashesAttribute.modules;
+ for (int i = 0; i < modules.size(); ++i) {
+ modules.set(i, remapper.mapModuleName(modules.get(i)));
+ }
+ }
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ RecordComponentVisitor recordComponentVisitor =
+ super.visitRecordComponent(
+ remapper.mapRecordComponentName(className, name, descriptor),
+ remapper.mapDesc(descriptor),
+ remapper.mapSignature(signature, true));
+ return recordComponentVisitor == null
+ ? null
+ : createRecordComponentRemapper(recordComponentVisitor);
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ FieldVisitor fieldVisitor =
+ super.visitField(
+ access,
+ remapper.mapFieldName(className, name, descriptor),
+ remapper.mapDesc(descriptor),
+ remapper.mapSignature(signature, true),
+ (value == null) ? null : remapper.mapValue(value));
+ return fieldVisitor == null ? null : createFieldRemapper(fieldVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ String remappedDescriptor = remapper.mapMethodDesc(descriptor);
+ MethodVisitor methodVisitor =
+ super.visitMethod(
+ access,
+ remapper.mapMethodName(className, name, descriptor),
+ remappedDescriptor,
+ remapper.mapSignature(signature, false),
+ exceptions == null ? null : remapper.mapTypes(exceptions));
+ return methodVisitor == null ? null : createMethodRemapper(methodVisitor);
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ super.visitInnerClass(
+ remapper.mapType(name),
+ outerName == null ? null : remapper.mapType(outerName),
+ innerName == null ? null : remapper.mapInnerClassName(name, outerName, innerName),
+ access);
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ super.visitOuterClass(
+ remapper.mapType(owner),
+ name == null ? null : remapper.mapMethodName(owner, name, descriptor),
+ descriptor == null ? null : remapper.mapMethodDesc(descriptor));
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ super.visitNestHost(remapper.mapType(nestHost));
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ super.visitNestMember(remapper.mapType(nestMember));
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ super.visitPermittedSubclass(remapper.mapType(permittedSubclass));
+ }
+
+ /**
+ * Constructs a new remapper for fields. The default implementation of this method returns a new
+ * {@link FieldRemapper}.
+ *
+ * @param fieldVisitor the FieldVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected FieldVisitor createFieldRemapper(final FieldVisitor fieldVisitor) {
+ return new FieldRemapper(api, fieldVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for methods. The default implementation of this method returns a new
+ * {@link MethodRemapper}.
+ *
+ * @param methodVisitor the MethodVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected MethodVisitor createMethodRemapper(final MethodVisitor methodVisitor) {
+ return new MethodRemapper(api, methodVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead.
+ */
+ @Deprecated
+ protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param descriptor the descriptor of the visited annotation.
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected AnnotationVisitor createAnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper)
+ .orDeprecatedValue(createAnnotationRemapper(annotationVisitor));
+ }
+
+ /**
+ * Constructs a new remapper for modules. The default implementation of this method returns a new
+ * {@link ModuleRemapper}.
+ *
+ * @param moduleVisitor the ModuleVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected ModuleVisitor createModuleRemapper(final ModuleVisitor moduleVisitor) {
+ return new ModuleRemapper(api, moduleVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for record components. The default implementation of this method
+ * returns a new {@link RecordComponentRemapper}.
+ *
+ * @param recordComponentVisitor the RecordComponentVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected RecordComponentVisitor createRecordComponentRemapper(
+ final RecordComponentVisitor recordComponentVisitor) {
+ return new RecordComponentRemapper(api, recordComponentVisitor, remapper);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java b/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java
new file mode 100644
index 00000000..148ad6ba
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java
@@ -0,0 +1,207 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link MethodVisitor} that approximates the size of the methods it visits.
+ *
+ * @author Eugene Kuleshov
+ */
+public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
+
+ /** The minimum size in bytes of the visited method. */
+ private int minSize;
+
+ /** The maximum size in bytes of the visited method. */
+ private int maxSize;
+
+ public CodeSizeEvaluator(final MethodVisitor methodVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, methodVisitor);
+ }
+
+ protected CodeSizeEvaluator(final int api, final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ }
+
+ public int getMinSize() {
+ return this.minSize;
+ }
+
+ public int getMaxSize() {
+ return this.maxSize;
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ minSize += 1;
+ maxSize += 1;
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ if (opcode == SIPUSH) {
+ minSize += 3;
+ maxSize += 3;
+ } else {
+ minSize += 2;
+ maxSize += 2;
+ }
+ super.visitIntInsn(opcode, operand);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ if (varIndex < 4 && opcode != RET) {
+ minSize += 1;
+ maxSize += 1;
+ } else if (varIndex >= 256) {
+ minSize += 4;
+ maxSize += 4;
+ } else {
+ minSize += 2;
+ maxSize += 2;
+ }
+ super.visitVarInsn(opcode, varIndex);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ minSize += 3;
+ maxSize += 3;
+ super.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ minSize += 3;
+ maxSize += 3;
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ if (opcode == INVOKEINTERFACE) {
+ minSize += 5;
+ maxSize += 5;
+ } else {
+ minSize += 3;
+ maxSize += 3;
+ }
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ minSize += 5;
+ maxSize += 5;
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ minSize += 3;
+ if (opcode == GOTO || opcode == JSR) {
+ maxSize += 5;
+ } else {
+ maxSize += 8;
+ }
+ super.visitJumpInsn(opcode, label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (value instanceof Long
+ || value instanceof Double
+ || (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
+ minSize += 3;
+ maxSize += 3;
+ } else {
+ minSize += 2;
+ maxSize += 3;
+ }
+ super.visitLdcInsn(value);
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ if (varIndex > 255 || increment > 127 || increment < -128) {
+ minSize += 6;
+ maxSize += 6;
+ } else {
+ minSize += 3;
+ maxSize += 3;
+ }
+ super.visitIincInsn(varIndex, increment);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ minSize += 13 + labels.length * 4;
+ maxSize += 16 + labels.length * 4;
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ minSize += 9 + keys.length * 8;
+ maxSize += 12 + keys.length * 8;
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ minSize += 4;
+ maxSize += 4;
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java
new file mode 100644
index 00000000..dc180224
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java
@@ -0,0 +1,115 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link FieldVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Eugene Kuleshov
+ */
+public class FieldRemapper extends FieldVisitor {
+
+ /** The remapper used to remap the types in the visited field. */
+ protected final Remapper remapper;
+
+ /**
+ * Constructs a new {@link FieldRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #FieldRemapper(int,FieldVisitor,Remapper)} version.
+ *
+ * @param fieldVisitor the field visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited field.
+ */
+ public FieldRemapper(final FieldVisitor fieldVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, fieldVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link FieldRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param fieldVisitor the field visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited field.
+ */
+ protected FieldRemapper(final int api, final FieldVisitor fieldVisitor, final Remapper remapper) {
+ super(api, fieldVisitor);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitAnnotation(remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead.
+ */
+ @Deprecated
+ protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param descriptor the descriptor of the visited annotation.
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected AnnotationVisitor createAnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper)
+ .orDeprecatedValue(createAnnotationRemapper(annotationVisitor));
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java
new file mode 100644
index 00000000..97f832b1
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java
@@ -0,0 +1,1369 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link MethodVisitor} with convenient methods to generate code. For example, using this
+ * adapter, the class below
+ *
+ * <pre>
+ * public class Example {
+ * public static void main(String[] args) {
+ * System.out.println(&quot;Hello world!&quot;);
+ * }
+ * }
+ * </pre>
+ *
+ * <p>can be generated as follows:
+ *
+ * <pre>
+ * ClassWriter cw = new ClassWriter(0);
+ * cw.visit(V1_1, ACC_PUBLIC, &quot;Example&quot;, null, &quot;java/lang/Object&quot;, null);
+ *
+ * Method m = Method.getMethod(&quot;void &lt;init&gt; ()&quot;);
+ * GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
+ * mg.loadThis();
+ * mg.invokeConstructor(Type.getType(Object.class), m);
+ * mg.returnValue();
+ * mg.endMethod();
+ *
+ * m = Method.getMethod(&quot;void main (String[])&quot;);
+ * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
+ * mg.getStatic(Type.getType(System.class), &quot;out&quot;, Type.getType(PrintStream.class));
+ * mg.push(&quot;Hello world!&quot;);
+ * mg.invokeVirtual(Type.getType(PrintStream.class),
+ * Method.getMethod(&quot;void println (String)&quot;));
+ * mg.returnValue();
+ * mg.endMethod();
+ *
+ * cw.visitEnd();
+ * </pre>
+ *
+ * @author Juozas Baliuka
+ * @author Chris Nokleberg
+ * @author Eric Bruneton
+ * @author Prashant Deva
+ */
+public class GeneratorAdapter extends LocalVariablesSorter {
+
+ private static final String CLASS_DESCRIPTOR = "Ljava/lang/Class;";
+
+ private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
+
+ private static final Type BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
+
+ private static final Type SHORT_TYPE = Type.getObjectType("java/lang/Short");
+
+ private static final Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character");
+
+ private static final Type INTEGER_TYPE = Type.getObjectType("java/lang/Integer");
+
+ private static final Type FLOAT_TYPE = Type.getObjectType("java/lang/Float");
+
+ private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long");
+
+ private static final Type DOUBLE_TYPE = Type.getObjectType("java/lang/Double");
+
+ private static final Type NUMBER_TYPE = Type.getObjectType("java/lang/Number");
+
+ private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
+
+ private static final Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()");
+
+ private static final Method CHAR_VALUE = Method.getMethod("char charValue()");
+
+ private static final Method INT_VALUE = Method.getMethod("int intValue()");
+
+ private static final Method FLOAT_VALUE = Method.getMethod("float floatValue()");
+
+ private static final Method LONG_VALUE = Method.getMethod("long longValue()");
+
+ private static final Method DOUBLE_VALUE = Method.getMethod("double doubleValue()");
+
+ /** Constant for the {@link #math} method. */
+ public static final int ADD = Opcodes.IADD;
+
+ /** Constant for the {@link #math} method. */
+ public static final int SUB = Opcodes.ISUB;
+
+ /** Constant for the {@link #math} method. */
+ public static final int MUL = Opcodes.IMUL;
+
+ /** Constant for the {@link #math} method. */
+ public static final int DIV = Opcodes.IDIV;
+
+ /** Constant for the {@link #math} method. */
+ public static final int REM = Opcodes.IREM;
+
+ /** Constant for the {@link #math} method. */
+ public static final int NEG = Opcodes.INEG;
+
+ /** Constant for the {@link #math} method. */
+ public static final int SHL = Opcodes.ISHL;
+
+ /** Constant for the {@link #math} method. */
+ public static final int SHR = Opcodes.ISHR;
+
+ /** Constant for the {@link #math} method. */
+ public static final int USHR = Opcodes.IUSHR;
+
+ /** Constant for the {@link #math} method. */
+ public static final int AND = Opcodes.IAND;
+
+ /** Constant for the {@link #math} method. */
+ public static final int OR = Opcodes.IOR;
+
+ /** Constant for the {@link #math} method. */
+ public static final int XOR = Opcodes.IXOR;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int EQ = Opcodes.IFEQ;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int NE = Opcodes.IFNE;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int LT = Opcodes.IFLT;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int GE = Opcodes.IFGE;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int GT = Opcodes.IFGT;
+
+ /** Constant for the {@link #ifCmp} method. */
+ public static final int LE = Opcodes.IFLE;
+
+ /** The access flags of the visited method. */
+ private final int access;
+
+ /** The name of the visited method. */
+ private final String name;
+
+ /** The return type of the visited method. */
+ private final Type returnType;
+
+ /** The argument types of the visited method. */
+ private final Type[] argumentTypes;
+
+ /** The types of the local variables of the visited method. */
+ private final List<Type> localTypes = new ArrayList<>();
+
+ /**
+ * Constructs a new {@link GeneratorAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+ * version.
+ *
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @throws IllegalStateException if a subclass calls this constructor.
+ */
+ public GeneratorAdapter(
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor) {
+ this(/* latest api = */ Opcodes.ASM9, methodVisitor, access, name, descriptor);
+ if (getClass() != GeneratorAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link GeneratorAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ */
+ protected GeneratorAdapter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor) {
+ super(api, access, descriptor, methodVisitor);
+ this.access = access;
+ this.name = name;
+ this.returnType = Type.getReturnType(descriptor);
+ this.argumentTypes = Type.getArgumentTypes(descriptor);
+ }
+
+ /**
+ * Constructs a new {@link GeneratorAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+ * version.
+ *
+ * @param access access flags of the adapted method.
+ * @param method the adapted method.
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ */
+ public GeneratorAdapter(
+ final int access, final Method method, final MethodVisitor methodVisitor) {
+ this(methodVisitor, access, method.getName(), method.getDescriptor());
+ }
+
+ /**
+ * Constructs a new {@link GeneratorAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+ * version.
+ *
+ * @param access access flags of the adapted method.
+ * @param method the adapted method.
+ * @param signature the signature of the adapted method (may be {@literal null}).
+ * @param exceptions the exceptions thrown by the adapted method (may be {@literal null}).
+ * @param classVisitor the class visitor to which this adapter delegates calls.
+ */
+ public GeneratorAdapter(
+ final int access,
+ final Method method,
+ final String signature,
+ final Type[] exceptions,
+ final ClassVisitor classVisitor) {
+ this(
+ access,
+ method,
+ classVisitor.visitMethod(
+ access,
+ method.getName(),
+ method.getDescriptor(),
+ signature,
+ exceptions == null ? null : getInternalNames(exceptions)));
+ }
+
+ /**
+ * Returns the internal names of the given types.
+ *
+ * @param types a set of types.
+ * @return the internal names of the given types (see {@link Type#getInternalName()}).
+ */
+ private static String[] getInternalNames(final Type[] types) {
+ String[] names = new String[types.length];
+ for (int i = 0; i < names.length; ++i) {
+ names[i] = types[i].getInternalName();
+ }
+ return names;
+ }
+
+ public int getAccess() {
+ return access;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Type getReturnType() {
+ return returnType;
+ }
+
+ public Type[] getArgumentTypes() {
+ return argumentTypes.clone();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to push constants on the stack
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final boolean value) {
+ push(value ? 1 : 0);
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final int value) {
+ if (value >= -1 && value <= 5) {
+ mv.visitInsn(Opcodes.ICONST_0 + value);
+ } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.BIPUSH, value);
+ } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, value);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final long value) {
+ if (value == 0L || value == 1L) {
+ mv.visitInsn(Opcodes.LCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final float value) {
+ int bits = Float.floatToIntBits(value);
+ if (bits == 0L || bits == 0x3F800000 || bits == 0x40000000) { // 0..2
+ mv.visitInsn(Opcodes.FCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final double value) {
+ long bits = Double.doubleToLongBits(value);
+ if (bits == 0L || bits == 0x3FF0000000000000L) { // +0.0d and 1.0d
+ mv.visitInsn(Opcodes.DCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack. May be {@literal null}.
+ */
+ public void push(final String value) {
+ if (value == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final Type value) {
+ if (value == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ switch (value.getSort()) {
+ case Type.BOOLEAN:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.CHAR:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.BYTE:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.SHORT:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.INT:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.FLOAT:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.LONG:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ case Type.DOUBLE:
+ mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", CLASS_DESCRIPTOR);
+ break;
+ default:
+ mv.visitLdcInsn(value);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Generates the instruction to push a handle on the stack.
+ *
+ * @param handle the handle to be pushed on the stack.
+ */
+ public void push(final Handle handle) {
+ if (handle == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(handle);
+ }
+ }
+
+ /**
+ * Generates the instruction to push a constant dynamic on the stack.
+ *
+ * @param constantDynamic the constant dynamic to be pushed on the stack.
+ */
+ public void push(final ConstantDynamic constantDynamic) {
+ if (constantDynamic == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(constantDynamic);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to load and store method arguments
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the index of the given method argument in the frame's local variables array.
+ *
+ * @param arg the index of a method argument.
+ * @return the index of the given method argument in the frame's local variables array.
+ */
+ private int getArgIndex(final int arg) {
+ int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0;
+ for (int i = 0; i < arg; i++) {
+ index += argumentTypes[i].getSize();
+ }
+ return index;
+ }
+
+ /**
+ * Generates the instruction to push a local variable on the stack.
+ *
+ * @param type the type of the local variable to be loaded.
+ * @param index an index in the frame's local variables array.
+ */
+ private void loadInsn(final Type type, final int index) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in a local variable.
+ *
+ * @param type the type of the local variable to be stored.
+ * @param index an index in the frame's local variables array.
+ */
+ private void storeInsn(final Type type, final int index) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index);
+ }
+
+ /** Generates the instruction to load 'this' on the stack. */
+ public void loadThis() {
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ throw new IllegalStateException("no 'this' pointer within static method");
+ }
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ }
+
+ /**
+ * Generates the instruction to load the given method argument on the stack.
+ *
+ * @param arg the index of a method argument.
+ */
+ public void loadArg(final int arg) {
+ loadInsn(argumentTypes[arg], getArgIndex(arg));
+ }
+
+ /**
+ * Generates the instructions to load the given method arguments on the stack.
+ *
+ * @param arg the index of the first method argument to be loaded.
+ * @param count the number of method arguments to be loaded.
+ */
+ public void loadArgs(final int arg, final int count) {
+ int index = getArgIndex(arg);
+ for (int i = 0; i < count; ++i) {
+ Type argumentType = argumentTypes[arg + i];
+ loadInsn(argumentType, index);
+ index += argumentType.getSize();
+ }
+ }
+
+ /** Generates the instructions to load all the method arguments on the stack. */
+ public void loadArgs() {
+ loadArgs(0, argumentTypes.length);
+ }
+
+ /**
+ * Generates the instructions to load all the method arguments on the stack, as a single object
+ * array.
+ */
+ public void loadArgArray() {
+ push(argumentTypes.length);
+ newArray(OBJECT_TYPE);
+ for (int i = 0; i < argumentTypes.length; i++) {
+ dup();
+ push(i);
+ loadArg(i);
+ box(argumentTypes[i]);
+ arrayStore(OBJECT_TYPE);
+ }
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given method argument.
+ *
+ * @param arg the index of a method argument.
+ */
+ public void storeArg(final int arg) {
+ storeInsn(argumentTypes[arg], getArgIndex(arg));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to load and store local variables
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the type of the given local variable.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ * @return the type of the given local variable.
+ */
+ public Type getLocalType(final int local) {
+ return localTypes.get(local - firstLocal);
+ }
+
+ @Override
+ protected void setLocalType(final int local, final Type type) {
+ int index = local - firstLocal;
+ while (localTypes.size() < index + 1) {
+ localTypes.add(null);
+ }
+ localTypes.set(index, type);
+ }
+
+ /**
+ * Generates the instruction to load the given local variable on the stack.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ */
+ public void loadLocal(final int local) {
+ loadInsn(getLocalType(local), local);
+ }
+
+ /**
+ * Generates the instruction to load the given local variable on the stack.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ * @param type the type of this local variable.
+ */
+ public void loadLocal(final int local, final Type type) {
+ setLocalType(local, type);
+ loadInsn(type, local);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given local variable.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ */
+ public void storeLocal(final int local) {
+ storeInsn(getLocalType(local), local);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given local variable.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ * @param type the type of this local variable.
+ */
+ public void storeLocal(final int local, final Type type) {
+ setLocalType(local, type);
+ storeInsn(type, local);
+ }
+
+ /**
+ * Generates the instruction to load an element from an array.
+ *
+ * @param type the type of the array element to be loaded.
+ */
+ public void arrayLoad(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
+ }
+
+ /**
+ * Generates the instruction to store an element in an array.
+ *
+ * @param type the type of the array element to be stored.
+ */
+ public void arrayStore(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to manage the stack
+ // -----------------------------------------------------------------------------------------------
+
+ /** Generates a POP instruction. */
+ public void pop() {
+ mv.visitInsn(Opcodes.POP);
+ }
+
+ /** Generates a POP2 instruction. */
+ public void pop2() {
+ mv.visitInsn(Opcodes.POP2);
+ }
+
+ /** Generates a DUP instruction. */
+ public void dup() {
+ mv.visitInsn(Opcodes.DUP);
+ }
+
+ /** Generates a DUP2 instruction. */
+ public void dup2() {
+ mv.visitInsn(Opcodes.DUP2);
+ }
+
+ /** Generates a DUP_X1 instruction. */
+ public void dupX1() {
+ mv.visitInsn(Opcodes.DUP_X1);
+ }
+
+ /** Generates a DUP_X2 instruction. */
+ public void dupX2() {
+ mv.visitInsn(Opcodes.DUP_X2);
+ }
+
+ /** Generates a DUP2_X1 instruction. */
+ public void dup2X1() {
+ mv.visitInsn(Opcodes.DUP2_X1);
+ }
+
+ /** Generates a DUP2_X2 instruction. */
+ public void dup2X2() {
+ mv.visitInsn(Opcodes.DUP2_X2);
+ }
+
+ /** Generates a SWAP instruction. */
+ public void swap() {
+ mv.visitInsn(Opcodes.SWAP);
+ }
+
+ /**
+ * Generates the instructions to swap the top two stack values.
+ *
+ * @param prev type of the top - 1 stack value.
+ * @param type type of the top stack value.
+ */
+ public void swap(final Type prev, final Type type) {
+ if (type.getSize() == 1) {
+ if (prev.getSize() == 1) {
+ swap(); // Same as dupX1 pop.
+ } else {
+ dupX2();
+ pop();
+ }
+ } else {
+ if (prev.getSize() == 1) {
+ dup2X1();
+ pop2();
+ } else {
+ dup2X2();
+ pop2();
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to do mathematical and logical operations
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Generates the instruction to do the specified mathematical or logical operation.
+ *
+ * @param op a mathematical or logical operation. Must be one of ADD, SUB, MUL, DIV, REM, NEG,
+ * SHL, SHR, USHR, AND, OR, XOR.
+ * @param type the type of the operand(s) for this operation.
+ */
+ public void math(final int op, final Type type) {
+ mv.visitInsn(type.getOpcode(op));
+ }
+
+ /** Generates the instructions to compute the bitwise negation of the top stack value. */
+ public void not() {
+ mv.visitInsn(Opcodes.ICONST_1);
+ mv.visitInsn(Opcodes.IXOR);
+ }
+
+ /**
+ * Generates the instruction to increment the given local variable.
+ *
+ * @param local the local variable to be incremented.
+ * @param amount the amount by which the local variable must be incremented.
+ */
+ public void iinc(final int local, final int amount) {
+ mv.visitIincInsn(local, amount);
+ }
+
+ /**
+ * Generates the instructions to cast a numerical value from one type to another.
+ *
+ * @param from the type of the top stack value
+ * @param to the type into which this value must be cast.
+ */
+ public void cast(final Type from, final Type to) {
+ if (from != to) {
+ if (from.getSort() < Type.BOOLEAN
+ || from.getSort() > Type.DOUBLE
+ || to.getSort() < Type.BOOLEAN
+ || to.getSort() > Type.DOUBLE) {
+ throw new IllegalArgumentException("Cannot cast from " + from + " to " + to);
+ }
+ InstructionAdapter.cast(mv, from, to);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to do boxing and unboxing operations
+ // -----------------------------------------------------------------------------------------------
+
+ private static Type getBoxedType(final Type type) {
+ switch (type.getSort()) {
+ case Type.BYTE:
+ return BYTE_TYPE;
+ case Type.BOOLEAN:
+ return BOOLEAN_TYPE;
+ case Type.SHORT:
+ return SHORT_TYPE;
+ case Type.CHAR:
+ return CHARACTER_TYPE;
+ case Type.INT:
+ return INTEGER_TYPE;
+ case Type.FLOAT:
+ return FLOAT_TYPE;
+ case Type.LONG:
+ return LONG_TYPE;
+ case Type.DOUBLE:
+ return DOUBLE_TYPE;
+ default:
+ return type;
+ }
+ }
+
+ /**
+ * Generates the instructions to box the top stack value. This value is replaced by its boxed
+ * equivalent on top of the stack.
+ *
+ * @param type the type of the top stack value.
+ */
+ public void box(final Type type) {
+ if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ return;
+ }
+ if (type == Type.VOID_TYPE) {
+ push((String) null);
+ } else {
+ Type boxedType = getBoxedType(type);
+ newInstance(boxedType);
+ if (type.getSize() == 2) {
+ // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
+ dupX2();
+ dupX2();
+ pop();
+ } else {
+ // p -> po -> opo -> oop -> o
+ dupX1();
+ swap();
+ }
+ invokeConstructor(boxedType, new Method("<init>", Type.VOID_TYPE, new Type[] {type}));
+ }
+ }
+
+ /**
+ * Generates the instructions to box the top stack value using Java 5's valueOf() method. This
+ * value is replaced by its boxed equivalent on top of the stack.
+ *
+ * @param type the type of the top stack value.
+ */
+ public void valueOf(final Type type) {
+ if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ return;
+ }
+ if (type == Type.VOID_TYPE) {
+ push((String) null);
+ } else {
+ Type boxedType = getBoxedType(type);
+ invokeStatic(boxedType, new Method("valueOf", boxedType, new Type[] {type}));
+ }
+ }
+
+ /**
+ * Generates the instructions to unbox the top stack value. This value is replaced by its unboxed
+ * equivalent on top of the stack.
+ *
+ * @param type the type of the top stack value.
+ */
+ public void unbox(final Type type) {
+ Type boxedType = NUMBER_TYPE;
+ Method unboxMethod;
+ switch (type.getSort()) {
+ case Type.VOID:
+ return;
+ case Type.CHAR:
+ boxedType = CHARACTER_TYPE;
+ unboxMethod = CHAR_VALUE;
+ break;
+ case Type.BOOLEAN:
+ boxedType = BOOLEAN_TYPE;
+ unboxMethod = BOOLEAN_VALUE;
+ break;
+ case Type.DOUBLE:
+ unboxMethod = DOUBLE_VALUE;
+ break;
+ case Type.FLOAT:
+ unboxMethod = FLOAT_VALUE;
+ break;
+ case Type.LONG:
+ unboxMethod = LONG_VALUE;
+ break;
+ case Type.INT:
+ case Type.SHORT:
+ case Type.BYTE:
+ unboxMethod = INT_VALUE;
+ break;
+ default:
+ unboxMethod = null;
+ break;
+ }
+ if (unboxMethod == null) {
+ checkCast(type);
+ } else {
+ checkCast(boxedType);
+ invokeVirtual(boxedType, unboxMethod);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to jump to other instructions
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link Label}.
+ *
+ * @return a new {@link Label}.
+ */
+ public Label newLabel() {
+ return new Label();
+ }
+
+ /**
+ * Marks the current code position with the given label.
+ *
+ * @param label a label.
+ */
+ public void mark(final Label label) {
+ mv.visitLabel(label);
+ }
+
+ /**
+ * Marks the current code position with a new label.
+ *
+ * @return the label that was created to mark the current code position.
+ */
+ public Label mark() {
+ Label label = new Label();
+ mv.visitLabel(label);
+ return label;
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of the top two stack
+ * values.
+ *
+ * @param type the type of the top two stack values.
+ * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, LE.
+ * @param label where to jump if the comparison result is {@literal true}.
+ */
+ public void ifCmp(final Type type, final int mode, final Label label) {
+ switch (type.getSort()) {
+ case Type.LONG:
+ mv.visitInsn(Opcodes.LCMP);
+ break;
+ case Type.DOUBLE:
+ mv.visitInsn(mode == GE || mode == GT ? Opcodes.DCMPL : Opcodes.DCMPG);
+ break;
+ case Type.FLOAT:
+ mv.visitInsn(mode == GE || mode == GT ? Opcodes.FCMPL : Opcodes.FCMPG);
+ break;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ if (mode == EQ) {
+ mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
+ return;
+ } else if (mode == NE) {
+ mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+ return;
+ } else {
+ throw new IllegalArgumentException("Bad comparison for type " + type);
+ }
+ default:
+ int intOp = -1;
+ switch (mode) {
+ case EQ:
+ intOp = Opcodes.IF_ICMPEQ;
+ break;
+ case NE:
+ intOp = Opcodes.IF_ICMPNE;
+ break;
+ case GE:
+ intOp = Opcodes.IF_ICMPGE;
+ break;
+ case LT:
+ intOp = Opcodes.IF_ICMPLT;
+ break;
+ case LE:
+ intOp = Opcodes.IF_ICMPLE;
+ break;
+ case GT:
+ intOp = Opcodes.IF_ICMPGT;
+ break;
+ default:
+ throw new IllegalArgumentException("Bad comparison mode " + mode);
+ }
+ mv.visitJumpInsn(intOp, label);
+ return;
+ }
+ mv.visitJumpInsn(mode, label);
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of the top two integer
+ * stack values.
+ *
+ * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, LE.
+ * @param label where to jump if the comparison result is {@literal true}.
+ */
+ public void ifICmp(final int mode, final Label label) {
+ ifCmp(Type.INT_TYPE, mode, label);
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of the top integer stack
+ * value with zero.
+ *
+ * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT, LE.
+ * @param label where to jump if the comparison result is {@literal true}.
+ */
+ public void ifZCmp(final int mode, final Label label) {
+ mv.visitJumpInsn(mode, label);
+ }
+
+ /**
+ * Generates the instruction to jump to the given label if the top stack value is null.
+ *
+ * @param label where to jump if the condition is {@literal true}.
+ */
+ public void ifNull(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFNULL, label);
+ }
+
+ /**
+ * Generates the instruction to jump to the given label if the top stack value is not null.
+ *
+ * @param label where to jump if the condition is {@literal true}.
+ */
+ public void ifNonNull(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFNONNULL, label);
+ }
+
+ /**
+ * Generates the instruction to jump to the given label.
+ *
+ * @param label where to jump if the condition is {@literal true}.
+ */
+ public void goTo(final Label label) {
+ mv.visitJumpInsn(Opcodes.GOTO, label);
+ }
+
+ /**
+ * Generates a RET instruction.
+ *
+ * @param local a local variable identifier, as returned by {@link
+ * LocalVariablesSorter#newLocal(Type)}.
+ */
+ public void ret(final int local) {
+ mv.visitVarInsn(Opcodes.RET, local);
+ }
+
+ /**
+ * Generates the instructions for a switch statement.
+ *
+ * @param keys the switch case keys.
+ * @param generator a generator to generate the code for the switch cases.
+ */
+ public void tableSwitch(final int[] keys, final TableSwitchGenerator generator) {
+ float density;
+ if (keys.length == 0) {
+ density = 0;
+ } else {
+ density = (float) keys.length / (keys[keys.length - 1] - keys[0] + 1);
+ }
+ tableSwitch(keys, generator, density >= 0.5f);
+ }
+
+ /**
+ * Generates the instructions for a switch statement.
+ *
+ * @param keys the switch case keys.
+ * @param generator a generator to generate the code for the switch cases.
+ * @param useTable {@literal true} to use a TABLESWITCH instruction, or {@literal false} to use a
+ * LOOKUPSWITCH instruction.
+ */
+ public void tableSwitch(
+ final int[] keys, final TableSwitchGenerator generator, final boolean useTable) {
+ for (int i = 1; i < keys.length; ++i) {
+ if (keys[i] < keys[i - 1]) {
+ throw new IllegalArgumentException("keys must be sorted in ascending order");
+ }
+ }
+ Label defaultLabel = newLabel();
+ Label endLabel = newLabel();
+ if (keys.length > 0) {
+ int numKeys = keys.length;
+ if (useTable) {
+ int min = keys[0];
+ int max = keys[numKeys - 1];
+ int range = max - min + 1;
+ Label[] labels = new Label[range];
+ Arrays.fill(labels, defaultLabel);
+ for (int i = 0; i < numKeys; ++i) {
+ labels[keys[i] - min] = newLabel();
+ }
+ mv.visitTableSwitchInsn(min, max, defaultLabel, labels);
+ for (int i = 0; i < range; ++i) {
+ Label label = labels[i];
+ if (label != defaultLabel) {
+ mark(label);
+ generator.generateCase(i + min, endLabel);
+ }
+ }
+ } else {
+ Label[] labels = new Label[numKeys];
+ for (int i = 0; i < numKeys; ++i) {
+ labels[i] = newLabel();
+ }
+ mv.visitLookupSwitchInsn(defaultLabel, keys, labels);
+ for (int i = 0; i < numKeys; ++i) {
+ mark(labels[i]);
+ generator.generateCase(keys[i], endLabel);
+ }
+ }
+ }
+ mark(defaultLabel);
+ generator.generateDefault();
+ mark(endLabel);
+ }
+
+ /** Generates the instruction to return the top stack value to the caller. */
+ public void returnValue() {
+ mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to load and store fields
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Generates a get field or set field instruction.
+ *
+ * @param opcode the instruction's opcode.
+ * @param ownerType the class in which the field is defined.
+ * @param name the name of the field.
+ * @param fieldType the type of the field.
+ */
+ private void fieldInsn(
+ final int opcode, final Type ownerType, final String name, final Type fieldType) {
+ mv.visitFieldInsn(opcode, ownerType.getInternalName(), name, fieldType.getDescriptor());
+ }
+
+ /**
+ * Generates the instruction to push the value of a static field on the stack.
+ *
+ * @param owner the class in which the field is defined.
+ * @param name the name of the field.
+ * @param type the type of the field.
+ */
+ public void getStatic(final Type owner, final String name, final Type type) {
+ fieldInsn(Opcodes.GETSTATIC, owner, name, type);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in a static field.
+ *
+ * @param owner the class in which the field is defined.
+ * @param name the name of the field.
+ * @param type the type of the field.
+ */
+ public void putStatic(final Type owner, final String name, final Type type) {
+ fieldInsn(Opcodes.PUTSTATIC, owner, name, type);
+ }
+
+ /**
+ * Generates the instruction to push the value of a non static field on the stack.
+ *
+ * @param owner the class in which the field is defined.
+ * @param name the name of the field.
+ * @param type the type of the field.
+ */
+ public void getField(final Type owner, final String name, final Type type) {
+ fieldInsn(Opcodes.GETFIELD, owner, name, type);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in a non static field.
+ *
+ * @param owner the class in which the field is defined.
+ * @param name the name of the field.
+ * @param type the type of the field.
+ */
+ public void putField(final Type owner, final String name, final Type type) {
+ fieldInsn(Opcodes.PUTFIELD, owner, name, type);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to invoke methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Generates an invoke method instruction.
+ *
+ * @param opcode the instruction's opcode.
+ * @param type the class in which the method is defined.
+ * @param method the method to be invoked.
+ * @param isInterface whether the 'type' class is an interface or not.
+ */
+ private void invokeInsn(
+ final int opcode, final Type type, final Method method, final boolean isInterface) {
+ String owner = type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName();
+ mv.visitMethodInsn(opcode, owner, method.getName(), method.getDescriptor(), isInterface);
+ }
+
+ /**
+ * Generates the instruction to invoke a normal method.
+ *
+ * @param owner the class in which the method is defined.
+ * @param method the method to be invoked.
+ */
+ public void invokeVirtual(final Type owner, final Method method) {
+ invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method, false);
+ }
+
+ /**
+ * Generates the instruction to invoke a constructor.
+ *
+ * @param type the class in which the constructor is defined.
+ * @param method the constructor to be invoked.
+ */
+ public void invokeConstructor(final Type type, final Method method) {
+ invokeInsn(Opcodes.INVOKESPECIAL, type, method, false);
+ }
+
+ /**
+ * Generates the instruction to invoke a static method.
+ *
+ * @param owner the class in which the method is defined.
+ * @param method the method to be invoked.
+ */
+ public void invokeStatic(final Type owner, final Method method) {
+ invokeInsn(Opcodes.INVOKESTATIC, owner, method, false);
+ }
+
+ /**
+ * Generates the instruction to invoke an interface method.
+ *
+ * @param owner the class in which the method is defined.
+ * @param method the method to be invoked.
+ */
+ public void invokeInterface(final Type owner, final Method method) {
+ invokeInsn(Opcodes.INVOKEINTERFACE, owner, method, true);
+ }
+
+ /**
+ * Generates an invokedynamic instruction.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
+ * Type} or {@link Handle} value. This method is allowed to modify the content of the array so
+ * a caller should expect that this array may change.
+ */
+ public void invokeDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ mv.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Instructions to create objects and arrays
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Generates a type dependent instruction.
+ *
+ * @param opcode the instruction's opcode.
+ * @param type the instruction's operand.
+ */
+ private void typeInsn(final int opcode, final Type type) {
+ mv.visitTypeInsn(opcode, type.getInternalName());
+ }
+
+ /**
+ * Generates the instruction to create a new object.
+ *
+ * @param type the class of the object to be created.
+ */
+ public void newInstance(final Type type) {
+ typeInsn(Opcodes.NEW, type);
+ }
+
+ /**
+ * Generates the instruction to create a new array.
+ *
+ * @param type the type of the array elements.
+ */
+ public void newArray(final Type type) {
+ InstructionAdapter.newarray(mv, type);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Miscellaneous instructions
+ // -----------------------------------------------------------------------------------------------
+
+ /** Generates the instruction to compute the length of an array. */
+ public void arrayLength() {
+ mv.visitInsn(Opcodes.ARRAYLENGTH);
+ }
+
+ /** Generates the instruction to throw an exception. */
+ public void throwException() {
+ mv.visitInsn(Opcodes.ATHROW);
+ }
+
+ /**
+ * Generates the instructions to create and throw an exception. The exception class must have a
+ * constructor with a single String argument.
+ *
+ * @param type the class of the exception to be thrown.
+ * @param message the detailed message of the exception.
+ */
+ public void throwException(final Type type, final String message) {
+ newInstance(type);
+ dup();
+ push(message);
+ invokeConstructor(type, Method.getMethod("void <init> (String)"));
+ throwException();
+ }
+
+ /**
+ * Generates the instruction to check that the top stack value is of the given type.
+ *
+ * @param type a class or interface type.
+ */
+ public void checkCast(final Type type) {
+ if (!type.equals(OBJECT_TYPE)) {
+ typeInsn(Opcodes.CHECKCAST, type);
+ }
+ }
+
+ /**
+ * Generates the instruction to test if the top stack value is of the given type.
+ *
+ * @param type a class or interface type.
+ */
+ public void instanceOf(final Type type) {
+ typeInsn(Opcodes.INSTANCEOF, type);
+ }
+
+ /** Generates the instruction to get the monitor of the top stack value. */
+ public void monitorEnter() {
+ mv.visitInsn(Opcodes.MONITORENTER);
+ }
+
+ /** Generates the instruction to release the monitor of the top stack value. */
+ public void monitorExit() {
+ mv.visitInsn(Opcodes.MONITOREXIT);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Non instructions
+ // -----------------------------------------------------------------------------------------------
+
+ /** Marks the end of the visited method. */
+ public void endMethod() {
+ if ((access & Opcodes.ACC_ABSTRACT) == 0) {
+ mv.visitMaxs(0, 0);
+ }
+ mv.visitEnd();
+ }
+
+ /**
+ * Marks the start of an exception handler.
+ *
+ * @param start beginning of the exception handler's scope (inclusive).
+ * @param end end of the exception handler's scope (exclusive).
+ * @param exception internal name of the type of exceptions handled by the handler (see {@link
+ * Type#getInternalName()}).
+ */
+ public void catchException(final Label start, final Label end, final Type exception) {
+ Label catchLabel = new Label();
+ if (exception == null) {
+ mv.visitTryCatchBlock(start, end, catchLabel, null);
+ } else {
+ mv.visitTryCatchBlock(start, end, catchLabel, exception.getInternalName());
+ }
+ mark(catchLabel);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java
new file mode 100644
index 00000000..afe8d689
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java
@@ -0,0 +1,1303 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link MethodVisitor} providing a more detailed API to generate and transform instructions.
+ *
+ * @author Eric Bruneton
+ */
+public class InstructionAdapter extends MethodVisitor {
+
+ /** The type of the java.lang.Object class. */
+ public static final Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
+
+ /**
+ * Constructs a new {@link InstructionAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #InstructionAdapter(int, MethodVisitor)} version.
+ *
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public InstructionAdapter(final MethodVisitor methodVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, methodVisitor);
+ if (getClass() != InstructionAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link InstructionAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ */
+ protected InstructionAdapter(final int api, final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ switch (opcode) {
+ case Opcodes.NOP:
+ nop();
+ break;
+ case Opcodes.ACONST_NULL:
+ aconst(null);
+ break;
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ iconst(opcode - Opcodes.ICONST_0);
+ break;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ lconst((long) (opcode - Opcodes.LCONST_0));
+ break;
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ fconst((float) (opcode - Opcodes.FCONST_0));
+ break;
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ dconst((double) (opcode - Opcodes.DCONST_0));
+ break;
+ case Opcodes.IALOAD:
+ aload(Type.INT_TYPE);
+ break;
+ case Opcodes.LALOAD:
+ aload(Type.LONG_TYPE);
+ break;
+ case Opcodes.FALOAD:
+ aload(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DALOAD:
+ aload(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.AALOAD:
+ aload(OBJECT_TYPE);
+ break;
+ case Opcodes.BALOAD:
+ aload(Type.BYTE_TYPE);
+ break;
+ case Opcodes.CALOAD:
+ aload(Type.CHAR_TYPE);
+ break;
+ case Opcodes.SALOAD:
+ aload(Type.SHORT_TYPE);
+ break;
+ case Opcodes.IASTORE:
+ astore(Type.INT_TYPE);
+ break;
+ case Opcodes.LASTORE:
+ astore(Type.LONG_TYPE);
+ break;
+ case Opcodes.FASTORE:
+ astore(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DASTORE:
+ astore(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.AASTORE:
+ astore(OBJECT_TYPE);
+ break;
+ case Opcodes.BASTORE:
+ astore(Type.BYTE_TYPE);
+ break;
+ case Opcodes.CASTORE:
+ astore(Type.CHAR_TYPE);
+ break;
+ case Opcodes.SASTORE:
+ astore(Type.SHORT_TYPE);
+ break;
+ case Opcodes.POP:
+ pop();
+ break;
+ case Opcodes.POP2:
+ pop2();
+ break;
+ case Opcodes.DUP:
+ dup();
+ break;
+ case Opcodes.DUP_X1:
+ dupX1();
+ break;
+ case Opcodes.DUP_X2:
+ dupX2();
+ break;
+ case Opcodes.DUP2:
+ dup2();
+ break;
+ case Opcodes.DUP2_X1:
+ dup2X1();
+ break;
+ case Opcodes.DUP2_X2:
+ dup2X2();
+ break;
+ case Opcodes.SWAP:
+ swap();
+ break;
+ case Opcodes.IADD:
+ add(Type.INT_TYPE);
+ break;
+ case Opcodes.LADD:
+ add(Type.LONG_TYPE);
+ break;
+ case Opcodes.FADD:
+ add(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DADD:
+ add(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.ISUB:
+ sub(Type.INT_TYPE);
+ break;
+ case Opcodes.LSUB:
+ sub(Type.LONG_TYPE);
+ break;
+ case Opcodes.FSUB:
+ sub(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DSUB:
+ sub(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.IMUL:
+ mul(Type.INT_TYPE);
+ break;
+ case Opcodes.LMUL:
+ mul(Type.LONG_TYPE);
+ break;
+ case Opcodes.FMUL:
+ mul(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DMUL:
+ mul(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.IDIV:
+ div(Type.INT_TYPE);
+ break;
+ case Opcodes.LDIV:
+ div(Type.LONG_TYPE);
+ break;
+ case Opcodes.FDIV:
+ div(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DDIV:
+ div(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.IREM:
+ rem(Type.INT_TYPE);
+ break;
+ case Opcodes.LREM:
+ rem(Type.LONG_TYPE);
+ break;
+ case Opcodes.FREM:
+ rem(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DREM:
+ rem(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.INEG:
+ neg(Type.INT_TYPE);
+ break;
+ case Opcodes.LNEG:
+ neg(Type.LONG_TYPE);
+ break;
+ case Opcodes.FNEG:
+ neg(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DNEG:
+ neg(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.ISHL:
+ shl(Type.INT_TYPE);
+ break;
+ case Opcodes.LSHL:
+ shl(Type.LONG_TYPE);
+ break;
+ case Opcodes.ISHR:
+ shr(Type.INT_TYPE);
+ break;
+ case Opcodes.LSHR:
+ shr(Type.LONG_TYPE);
+ break;
+ case Opcodes.IUSHR:
+ ushr(Type.INT_TYPE);
+ break;
+ case Opcodes.LUSHR:
+ ushr(Type.LONG_TYPE);
+ break;
+ case Opcodes.IAND:
+ and(Type.INT_TYPE);
+ break;
+ case Opcodes.LAND:
+ and(Type.LONG_TYPE);
+ break;
+ case Opcodes.IOR:
+ or(Type.INT_TYPE);
+ break;
+ case Opcodes.LOR:
+ or(Type.LONG_TYPE);
+ break;
+ case Opcodes.IXOR:
+ xor(Type.INT_TYPE);
+ break;
+ case Opcodes.LXOR:
+ xor(Type.LONG_TYPE);
+ break;
+ case Opcodes.I2L:
+ cast(Type.INT_TYPE, Type.LONG_TYPE);
+ break;
+ case Opcodes.I2F:
+ cast(Type.INT_TYPE, Type.FLOAT_TYPE);
+ break;
+ case Opcodes.I2D:
+ cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.L2I:
+ cast(Type.LONG_TYPE, Type.INT_TYPE);
+ break;
+ case Opcodes.L2F:
+ cast(Type.LONG_TYPE, Type.FLOAT_TYPE);
+ break;
+ case Opcodes.L2D:
+ cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.F2I:
+ cast(Type.FLOAT_TYPE, Type.INT_TYPE);
+ break;
+ case Opcodes.F2L:
+ cast(Type.FLOAT_TYPE, Type.LONG_TYPE);
+ break;
+ case Opcodes.F2D:
+ cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.D2I:
+ cast(Type.DOUBLE_TYPE, Type.INT_TYPE);
+ break;
+ case Opcodes.D2L:
+ cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);
+ break;
+ case Opcodes.D2F:
+ cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
+ break;
+ case Opcodes.I2B:
+ cast(Type.INT_TYPE, Type.BYTE_TYPE);
+ break;
+ case Opcodes.I2C:
+ cast(Type.INT_TYPE, Type.CHAR_TYPE);
+ break;
+ case Opcodes.I2S:
+ cast(Type.INT_TYPE, Type.SHORT_TYPE);
+ break;
+ case Opcodes.LCMP:
+ lcmp();
+ break;
+ case Opcodes.FCMPL:
+ cmpl(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.FCMPG:
+ cmpg(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DCMPL:
+ cmpl(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.DCMPG:
+ cmpg(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.IRETURN:
+ areturn(Type.INT_TYPE);
+ break;
+ case Opcodes.LRETURN:
+ areturn(Type.LONG_TYPE);
+ break;
+ case Opcodes.FRETURN:
+ areturn(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DRETURN:
+ areturn(Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.ARETURN:
+ areturn(OBJECT_TYPE);
+ break;
+ case Opcodes.RETURN:
+ areturn(Type.VOID_TYPE);
+ break;
+ case Opcodes.ARRAYLENGTH:
+ arraylength();
+ break;
+ case Opcodes.ATHROW:
+ athrow();
+ break;
+ case Opcodes.MONITORENTER:
+ monitorenter();
+ break;
+ case Opcodes.MONITOREXIT:
+ monitorexit();
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ switch (opcode) {
+ case Opcodes.BIPUSH:
+ iconst(operand);
+ break;
+ case Opcodes.SIPUSH:
+ iconst(operand);
+ break;
+ case Opcodes.NEWARRAY:
+ switch (operand) {
+ case Opcodes.T_BOOLEAN:
+ newarray(Type.BOOLEAN_TYPE);
+ break;
+ case Opcodes.T_CHAR:
+ newarray(Type.CHAR_TYPE);
+ break;
+ case Opcodes.T_BYTE:
+ newarray(Type.BYTE_TYPE);
+ break;
+ case Opcodes.T_SHORT:
+ newarray(Type.SHORT_TYPE);
+ break;
+ case Opcodes.T_INT:
+ newarray(Type.INT_TYPE);
+ break;
+ case Opcodes.T_FLOAT:
+ newarray(Type.FLOAT_TYPE);
+ break;
+ case Opcodes.T_LONG:
+ newarray(Type.LONG_TYPE);
+ break;
+ case Opcodes.T_DOUBLE:
+ newarray(Type.DOUBLE_TYPE);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ switch (opcode) {
+ case Opcodes.ILOAD:
+ load(varIndex, Type.INT_TYPE);
+ break;
+ case Opcodes.LLOAD:
+ load(varIndex, Type.LONG_TYPE);
+ break;
+ case Opcodes.FLOAD:
+ load(varIndex, Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DLOAD:
+ load(varIndex, Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.ALOAD:
+ load(varIndex, OBJECT_TYPE);
+ break;
+ case Opcodes.ISTORE:
+ store(varIndex, Type.INT_TYPE);
+ break;
+ case Opcodes.LSTORE:
+ store(varIndex, Type.LONG_TYPE);
+ break;
+ case Opcodes.FSTORE:
+ store(varIndex, Type.FLOAT_TYPE);
+ break;
+ case Opcodes.DSTORE:
+ store(varIndex, Type.DOUBLE_TYPE);
+ break;
+ case Opcodes.ASTORE:
+ store(varIndex, OBJECT_TYPE);
+ break;
+ case Opcodes.RET:
+ ret(varIndex);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ Type objectType = Type.getObjectType(type);
+ switch (opcode) {
+ case Opcodes.NEW:
+ anew(objectType);
+ break;
+ case Opcodes.ANEWARRAY:
+ newarray(objectType);
+ break;
+ case Opcodes.CHECKCAST:
+ checkcast(objectType);
+ break;
+ case Opcodes.INSTANCEOF:
+ instanceOf(objectType);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ switch (opcode) {
+ case Opcodes.GETSTATIC:
+ getstatic(owner, name, descriptor);
+ break;
+ case Opcodes.PUTSTATIC:
+ putstatic(owner, name, descriptor);
+ break;
+ case Opcodes.GETFIELD:
+ getfield(owner, name, descriptor);
+ break;
+ case Opcodes.PUTFIELD:
+ putfield(owner, name, descriptor);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ switch (opcode) {
+ case Opcodes.INVOKESPECIAL:
+ invokespecial(owner, name, descriptor, isInterface);
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ invokevirtual(owner, name, descriptor, isInterface);
+ break;
+ case Opcodes.INVOKESTATIC:
+ invokestatic(owner, name, descriptor, isInterface);
+ break;
+ case Opcodes.INVOKEINTERFACE:
+ invokeinterface(owner, name, descriptor);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ invokedynamic(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ switch (opcode) {
+ case Opcodes.IFEQ:
+ ifeq(label);
+ break;
+ case Opcodes.IFNE:
+ ifne(label);
+ break;
+ case Opcodes.IFLT:
+ iflt(label);
+ break;
+ case Opcodes.IFGE:
+ ifge(label);
+ break;
+ case Opcodes.IFGT:
+ ifgt(label);
+ break;
+ case Opcodes.IFLE:
+ ifle(label);
+ break;
+ case Opcodes.IF_ICMPEQ:
+ ificmpeq(label);
+ break;
+ case Opcodes.IF_ICMPNE:
+ ificmpne(label);
+ break;
+ case Opcodes.IF_ICMPLT:
+ ificmplt(label);
+ break;
+ case Opcodes.IF_ICMPGE:
+ ificmpge(label);
+ break;
+ case Opcodes.IF_ICMPGT:
+ ificmpgt(label);
+ break;
+ case Opcodes.IF_ICMPLE:
+ ificmple(label);
+ break;
+ case Opcodes.IF_ACMPEQ:
+ ifacmpeq(label);
+ break;
+ case Opcodes.IF_ACMPNE:
+ ifacmpne(label);
+ break;
+ case Opcodes.GOTO:
+ goTo(label);
+ break;
+ case Opcodes.JSR:
+ jsr(label);
+ break;
+ case Opcodes.IFNULL:
+ ifnull(label);
+ break;
+ case Opcodes.IFNONNULL:
+ ifnonnull(label);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ mark(label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (api < Opcodes.ASM5
+ && (value instanceof Handle
+ || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
+ throw new UnsupportedOperationException("This feature requires ASM5");
+ }
+ if (api < Opcodes.ASM7 && value instanceof ConstantDynamic) {
+ throw new UnsupportedOperationException("This feature requires ASM7");
+ }
+ if (value instanceof Integer) {
+ iconst((Integer) value);
+ } else if (value instanceof Byte) {
+ iconst(((Byte) value).intValue());
+ } else if (value instanceof Character) {
+ iconst(((Character) value).charValue());
+ } else if (value instanceof Short) {
+ iconst(((Short) value).intValue());
+ } else if (value instanceof Boolean) {
+ iconst(((Boolean) value).booleanValue() ? 1 : 0);
+ } else if (value instanceof Float) {
+ fconst((Float) value);
+ } else if (value instanceof Long) {
+ lconst((Long) value);
+ } else if (value instanceof Double) {
+ dconst((Double) value);
+ } else if (value instanceof String) {
+ aconst(value);
+ } else if (value instanceof Type) {
+ tconst((Type) value);
+ } else if (value instanceof Handle) {
+ hconst((Handle) value);
+ } else if (value instanceof ConstantDynamic) {
+ cconst((ConstantDynamic) value);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ iinc(varIndex, increment);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ tableswitch(min, max, dflt, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ lookupswitch(dflt, keys, labels);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ multianewarray(descriptor, numDimensions);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ /** Generates a nop instruction. */
+ public void nop() {
+ mv.visitInsn(Opcodes.NOP);
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the constant to be pushed on the stack. This parameter must be an {@link Integer},
+ * a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link Type} of
+ * OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is 49, a
+ * {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle constants,
+ * for classes whose version is 51 or a {@link ConstantDynamic} for a constant dynamic for
+ * classes whose version is 55.
+ */
+ public void aconst(final Object value) {
+ if (value == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param intValue the constant to be pushed on the stack.
+ */
+ public void iconst(final int intValue) {
+ if (intValue >= -1 && intValue <= 5) {
+ mv.visitInsn(Opcodes.ICONST_0 + intValue);
+ } else if (intValue >= Byte.MIN_VALUE && intValue <= Byte.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.BIPUSH, intValue);
+ } else if (intValue >= Short.MIN_VALUE && intValue <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, intValue);
+ } else {
+ mv.visitLdcInsn(intValue);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param longValue the constant to be pushed on the stack.
+ */
+ public void lconst(final long longValue) {
+ if (longValue == 0L || longValue == 1L) {
+ mv.visitInsn(Opcodes.LCONST_0 + (int) longValue);
+ } else {
+ mv.visitLdcInsn(longValue);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param floatValue the constant to be pushed on the stack.
+ */
+ public void fconst(final float floatValue) {
+ int bits = Float.floatToIntBits(floatValue);
+ if (bits == 0L || bits == 0x3F800000 || bits == 0x40000000) { // 0..2
+ mv.visitInsn(Opcodes.FCONST_0 + (int) floatValue);
+ } else {
+ mv.visitLdcInsn(floatValue);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param doubleValue the constant to be pushed on the stack.
+ */
+ public void dconst(final double doubleValue) {
+ long bits = Double.doubleToLongBits(doubleValue);
+ if (bits == 0L || bits == 0x3FF0000000000000L) { // +0.0d and 1.0d
+ mv.visitInsn(Opcodes.DCONST_0 + (int) doubleValue);
+ } else {
+ mv.visitLdcInsn(doubleValue);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given type on the stack.
+ *
+ * @param type the type to be pushed on the stack.
+ */
+ public void tconst(final Type type) {
+ mv.visitLdcInsn(type);
+ }
+
+ /**
+ * Generates the instruction to push the given handle on the stack.
+ *
+ * @param handle the handle to be pushed on the stack.
+ */
+ public void hconst(final Handle handle) {
+ mv.visitLdcInsn(handle);
+ }
+
+ /**
+ * Generates the instruction to push the given constant dynamic on the stack.
+ *
+ * @param constantDynamic the constant dynamic to be pushed on the stack.
+ */
+ public void cconst(final ConstantDynamic constantDynamic) {
+ mv.visitLdcInsn(constantDynamic);
+ }
+
+ public void load(final int varIndex, final Type type) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), varIndex);
+ }
+
+ public void aload(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
+ }
+
+ public void store(final int varIndex, final Type type) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), varIndex);
+ }
+
+ public void astore(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
+ }
+
+ public void pop() {
+ mv.visitInsn(Opcodes.POP);
+ }
+
+ public void pop2() {
+ mv.visitInsn(Opcodes.POP2);
+ }
+
+ public void dup() {
+ mv.visitInsn(Opcodes.DUP);
+ }
+
+ public void dup2() {
+ mv.visitInsn(Opcodes.DUP2);
+ }
+
+ public void dupX1() {
+ mv.visitInsn(Opcodes.DUP_X1);
+ }
+
+ public void dupX2() {
+ mv.visitInsn(Opcodes.DUP_X2);
+ }
+
+ public void dup2X1() {
+ mv.visitInsn(Opcodes.DUP2_X1);
+ }
+
+ public void dup2X2() {
+ mv.visitInsn(Opcodes.DUP2_X2);
+ }
+
+ public void swap() {
+ mv.visitInsn(Opcodes.SWAP);
+ }
+
+ public void add(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IADD));
+ }
+
+ public void sub(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.ISUB));
+ }
+
+ public void mul(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IMUL));
+ }
+
+ public void div(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IDIV));
+ }
+
+ public void rem(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IREM));
+ }
+
+ public void neg(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.INEG));
+ }
+
+ public void shl(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.ISHL));
+ }
+
+ public void shr(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.ISHR));
+ }
+
+ public void ushr(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IUSHR));
+ }
+
+ public void and(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IAND));
+ }
+
+ public void or(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IOR));
+ }
+
+ public void xor(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IXOR));
+ }
+
+ public void iinc(final int varIndex, final int increment) {
+ mv.visitIincInsn(varIndex, increment);
+ }
+
+ /**
+ * Generates the instruction to cast from the first given type to the other.
+ *
+ * @param from a Type.
+ * @param to a Type.
+ */
+ public void cast(final Type from, final Type to) {
+ cast(mv, from, to);
+ }
+
+ /**
+ * Generates the instruction to cast from the first given type to the other.
+ *
+ * @param methodVisitor the method visitor to use to generate the instruction.
+ * @param from a Type.
+ * @param to a Type.
+ */
+ static void cast(final MethodVisitor methodVisitor, final Type from, final Type to) {
+ if (from != to) {
+ if (from == Type.DOUBLE_TYPE) {
+ if (to == Type.FLOAT_TYPE) {
+ methodVisitor.visitInsn(Opcodes.D2F);
+ } else if (to == Type.LONG_TYPE) {
+ methodVisitor.visitInsn(Opcodes.D2L);
+ } else {
+ methodVisitor.visitInsn(Opcodes.D2I);
+ cast(methodVisitor, Type.INT_TYPE, to);
+ }
+ } else if (from == Type.FLOAT_TYPE) {
+ if (to == Type.DOUBLE_TYPE) {
+ methodVisitor.visitInsn(Opcodes.F2D);
+ } else if (to == Type.LONG_TYPE) {
+ methodVisitor.visitInsn(Opcodes.F2L);
+ } else {
+ methodVisitor.visitInsn(Opcodes.F2I);
+ cast(methodVisitor, Type.INT_TYPE, to);
+ }
+ } else if (from == Type.LONG_TYPE) {
+ if (to == Type.DOUBLE_TYPE) {
+ methodVisitor.visitInsn(Opcodes.L2D);
+ } else if (to == Type.FLOAT_TYPE) {
+ methodVisitor.visitInsn(Opcodes.L2F);
+ } else {
+ methodVisitor.visitInsn(Opcodes.L2I);
+ cast(methodVisitor, Type.INT_TYPE, to);
+ }
+ } else {
+ if (to == Type.BYTE_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2B);
+ } else if (to == Type.CHAR_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2C);
+ } else if (to == Type.DOUBLE_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2D);
+ } else if (to == Type.FLOAT_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2F);
+ } else if (to == Type.LONG_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2L);
+ } else if (to == Type.SHORT_TYPE) {
+ methodVisitor.visitInsn(Opcodes.I2S);
+ }
+ }
+ }
+ }
+
+ public void lcmp() {
+ mv.visitInsn(Opcodes.LCMP);
+ }
+
+ public void cmpl(final Type type) {
+ mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPL : Opcodes.DCMPL);
+ }
+
+ public void cmpg(final Type type) {
+ mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPG : Opcodes.DCMPG);
+ }
+
+ public void ifeq(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFEQ, label);
+ }
+
+ public void ifne(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFNE, label);
+ }
+
+ public void iflt(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFLT, label);
+ }
+
+ public void ifge(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFGE, label);
+ }
+
+ public void ifgt(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFGT, label);
+ }
+
+ public void ifle(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFLE, label);
+ }
+
+ public void ificmpeq(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPEQ, label);
+ }
+
+ public void ificmpne(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPNE, label);
+ }
+
+ public void ificmplt(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPLT, label);
+ }
+
+ public void ificmpge(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPGE, label);
+ }
+
+ public void ificmpgt(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPGT, label);
+ }
+
+ public void ificmple(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ICMPLE, label);
+ }
+
+ public void ifacmpeq(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
+ }
+
+ public void ifacmpne(final Label label) {
+ mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+ }
+
+ public void goTo(final Label label) {
+ mv.visitJumpInsn(Opcodes.GOTO, label);
+ }
+
+ public void jsr(final Label label) {
+ mv.visitJumpInsn(Opcodes.JSR, label);
+ }
+
+ public void ret(final int varIndex) {
+ mv.visitVarInsn(Opcodes.RET, varIndex);
+ }
+
+ public void tableswitch(final int min, final int max, final Label dflt, final Label... labels) {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ public void lookupswitch(final Label dflt, final int[] keys, final Label[] labels) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ public void areturn(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IRETURN));
+ }
+
+ public void getstatic(final String owner, final String name, final String descriptor) {
+ mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, descriptor);
+ }
+
+ public void putstatic(final String owner, final String name, final String descriptor) {
+ mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, descriptor);
+ }
+
+ public void getfield(final String owner, final String name, final String descriptor) {
+ mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, descriptor);
+ }
+
+ public void putfield(final String owner, final String name, final String descriptor) {
+ mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, descriptor);
+ }
+
+ /**
+ * Deprecated.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @deprecated use {@link #invokevirtual(String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ public void invokevirtual(final String owner, final String name, final String descriptor) {
+ if (api >= Opcodes.ASM5) {
+ invokevirtual(owner, name, descriptor, false);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, descriptor);
+ }
+
+ /**
+ * Generates the instruction to call the given virtual method.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public void invokevirtual(
+ final String owner, final String name, final String descriptor, final boolean isInterface) {
+ if (api < Opcodes.ASM5) {
+ if (isInterface) {
+ throw new UnsupportedOperationException("INVOKEVIRTUAL on interfaces require ASM 5");
+ }
+ invokevirtual(owner, name, descriptor);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, descriptor, isInterface);
+ }
+
+ /**
+ * Deprecated.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @deprecated use {@link #invokespecial(String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ public void invokespecial(final String owner, final String name, final String descriptor) {
+ if (api >= Opcodes.ASM5) {
+ invokespecial(owner, name, descriptor, false);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, descriptor, false);
+ }
+
+ /**
+ * Generates the instruction to call the given special method.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public void invokespecial(
+ final String owner, final String name, final String descriptor, final boolean isInterface) {
+ if (api < Opcodes.ASM5) {
+ if (isInterface) {
+ throw new UnsupportedOperationException("INVOKESPECIAL on interfaces require ASM 5");
+ }
+ invokespecial(owner, name, descriptor);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, descriptor, isInterface);
+ }
+
+ /**
+ * Deprecated.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @deprecated use {@link #invokestatic(String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ public void invokestatic(final String owner, final String name, final String descriptor) {
+ if (api >= Opcodes.ASM5) {
+ invokestatic(owner, name, descriptor, false);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, descriptor, false);
+ }
+
+ /**
+ * Generates the instruction to call the given static method.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public void invokestatic(
+ final String owner, final String name, final String descriptor, final boolean isInterface) {
+ if (api < Opcodes.ASM5) {
+ if (isInterface) {
+ throw new UnsupportedOperationException("INVOKESTATIC on interfaces require ASM 5");
+ }
+ invokestatic(owner, name, descriptor);
+ return;
+ }
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, descriptor, isInterface);
+ }
+
+ /**
+ * Generates the instruction to call the given interface method.
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ */
+ public void invokeinterface(final String owner, final String name, final String descriptor) {
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, descriptor, true);
+ }
+
+ /**
+ * Generates the instruction to call the given dynamic method.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
+ * Type}, {@link Handle} or {@link ConstantDynamic} value. This method is allowed to modify
+ * the content of the array so a caller should expect that this array may change.
+ */
+ public void invokedynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object[] bootstrapMethodArguments) {
+ mv.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ public void anew(final Type type) {
+ mv.visitTypeInsn(Opcodes.NEW, type.getInternalName());
+ }
+
+ /**
+ * Generates the instruction to create and push on the stack an array of the given type.
+ *
+ * @param type an array Type.
+ */
+ public void newarray(final Type type) {
+ newarray(mv, type);
+ }
+
+ /**
+ * Generates the instruction to create and push on the stack an array of the given type.
+ *
+ * @param methodVisitor the method visitor to use to generate the instruction.
+ * @param type an array Type.
+ */
+ static void newarray(final MethodVisitor methodVisitor, final Type type) {
+ int arrayType;
+ switch (type.getSort()) {
+ case Type.BOOLEAN:
+ arrayType = Opcodes.T_BOOLEAN;
+ break;
+ case Type.CHAR:
+ arrayType = Opcodes.T_CHAR;
+ break;
+ case Type.BYTE:
+ arrayType = Opcodes.T_BYTE;
+ break;
+ case Type.SHORT:
+ arrayType = Opcodes.T_SHORT;
+ break;
+ case Type.INT:
+ arrayType = Opcodes.T_INT;
+ break;
+ case Type.FLOAT:
+ arrayType = Opcodes.T_FLOAT;
+ break;
+ case Type.LONG:
+ arrayType = Opcodes.T_LONG;
+ break;
+ case Type.DOUBLE:
+ arrayType = Opcodes.T_DOUBLE;
+ break;
+ default:
+ methodVisitor.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
+ return;
+ }
+ methodVisitor.visitIntInsn(Opcodes.NEWARRAY, arrayType);
+ }
+
+ public void arraylength() {
+ mv.visitInsn(Opcodes.ARRAYLENGTH);
+ }
+
+ public void athrow() {
+ mv.visitInsn(Opcodes.ATHROW);
+ }
+
+ public void checkcast(final Type type) {
+ mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
+ }
+
+ public void instanceOf(final Type type) {
+ mv.visitTypeInsn(Opcodes.INSTANCEOF, type.getInternalName());
+ }
+
+ public void monitorenter() {
+ mv.visitInsn(Opcodes.MONITORENTER);
+ }
+
+ public void monitorexit() {
+ mv.visitInsn(Opcodes.MONITOREXIT);
+ }
+
+ public void multianewarray(final String descriptor, final int numDimensions) {
+ mv.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+
+ public void ifnull(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFNULL, label);
+ }
+
+ public void ifnonnull(final Label label) {
+ mv.visitJumpInsn(Opcodes.IFNONNULL, label);
+ }
+
+ public void mark(final Label label) {
+ mv.visitLabel(label);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java
new file mode 100644
index 00000000..e1beedfc
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java
@@ -0,0 +1,572 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LocalVariableNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+
+/**
+ * A {@link org.objectweb.asm.MethodVisitor} that removes JSR instructions and inlines the
+ * referenced subroutines.
+ *
+ * @author Niko Matsakis
+ */
+// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+public class JSRInlinerAdapter extends MethodNode implements Opcodes {
+
+ /**
+ * The instructions that belong to the main "subroutine". Bit i is set iff instruction at index i
+ * belongs to this main "subroutine".
+ */
+ private final BitSet mainSubroutineInsns = new BitSet();
+
+ /**
+ * The instructions that belong to each subroutine. For each label which is the target of a JSR
+ * instruction, bit i of the corresponding BitSet in this map is set iff instruction at index i
+ * belongs to this subroutine.
+ */
+ private final Map<LabelNode, BitSet> subroutinesInsns = new HashMap<>();
+
+ /**
+ * The instructions that belong to more that one subroutine. Bit i is set iff instruction at index
+ * i belongs to more than one subroutine.
+ */
+ final BitSet sharedSubroutineInsns = new BitSet();
+
+ /**
+ * Constructs a new {@link JSRInlinerAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String,
+ * String, String[])} version.
+ *
+ * @param methodVisitor the method visitor to send the resulting inlined method code to, or <code>
+ * null</code>.
+ * @param access the method's access flags.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor.
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ * @throws IllegalStateException if a subclass calls this constructor.
+ */
+ public JSRInlinerAdapter(
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ this(
+ /* latest api = */ Opcodes.ASM9,
+ methodVisitor,
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions);
+ if (getClass() != JSRInlinerAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link JSRInlinerAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to send the resulting inlined method code to, or <code>
+ * null</code>.
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor.
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ protected JSRInlinerAdapter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ super(api, access, name, descriptor, signature, exceptions);
+ this.mv = methodVisitor;
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ super.visitJumpInsn(opcode, label);
+ LabelNode labelNode = ((JumpInsnNode) instructions.getLast()).label;
+ if (opcode == JSR && !subroutinesInsns.containsKey(labelNode)) {
+ subroutinesInsns.put(labelNode, new BitSet());
+ }
+ }
+
+ @Override
+ public void visitEnd() {
+ if (!subroutinesInsns.isEmpty()) {
+ // If the code contains at least one JSR instruction, inline the subroutines.
+ findSubroutinesInsns();
+ emitCode();
+ }
+ if (mv != null) {
+ accept(mv);
+ }
+ }
+
+ /** Determines, for each instruction, to which subroutine(s) it belongs. */
+ private void findSubroutinesInsns() {
+ // Find the instructions that belong to main subroutine.
+ BitSet visitedInsns = new BitSet();
+ findSubroutineInsns(0, mainSubroutineInsns, visitedInsns);
+ // For each subroutine, find the instructions that belong to this subroutine.
+ for (Map.Entry<LabelNode, BitSet> entry : subroutinesInsns.entrySet()) {
+ LabelNode jsrLabelNode = entry.getKey();
+ BitSet subroutineInsns = entry.getValue();
+ findSubroutineInsns(instructions.indexOf(jsrLabelNode), subroutineInsns, visitedInsns);
+ }
+ }
+
+ /**
+ * Finds the instructions that belong to the subroutine starting at the given instruction index.
+ * For this the control flow graph is visited with a depth first search (this includes the normal
+ * control flow and the exception handlers).
+ *
+ * @param startInsnIndex the index of the first instruction of the subroutine.
+ * @param subroutineInsns where the indices of the instructions of the subroutine must be stored.
+ * @param visitedInsns the indices of the instructions that have been visited so far (including in
+ * previous calls to this method). This bitset is updated by this method each time a new
+ * instruction is visited. It is used to make sure each instruction is visited at most once.
+ */
+ private void findSubroutineInsns(
+ final int startInsnIndex, final BitSet subroutineInsns, final BitSet visitedInsns) {
+ // First find the instructions reachable via normal execution.
+ findReachableInsns(startInsnIndex, subroutineInsns, visitedInsns);
+
+ // Then find the instructions reachable via the applicable exception handlers.
+ while (true) {
+ boolean applicableHandlerFound = false;
+ for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlocks) {
+ // If the handler has already been processed, skip it.
+ int handlerIndex = instructions.indexOf(tryCatchBlockNode.handler);
+ if (subroutineInsns.get(handlerIndex)) {
+ continue;
+ }
+
+ // If an instruction in the exception handler range belongs to the subroutine, the handler
+ // can be reached from the routine, and its instructions must be added to the subroutine.
+ int startIndex = instructions.indexOf(tryCatchBlockNode.start);
+ int endIndex = instructions.indexOf(tryCatchBlockNode.end);
+ int firstSubroutineInsnAfterTryCatchStart = subroutineInsns.nextSetBit(startIndex);
+ if (firstSubroutineInsnAfterTryCatchStart >= startIndex
+ && firstSubroutineInsnAfterTryCatchStart < endIndex) {
+ findReachableInsns(handlerIndex, subroutineInsns, visitedInsns);
+ applicableHandlerFound = true;
+ }
+ }
+ // If an applicable exception handler has been found, other handlers may become applicable, so
+ // we must examine them again.
+ if (!applicableHandlerFound) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Finds the instructions that are reachable from the given instruction, without following any JSR
+ * instruction nor any exception handler. For this the control flow graph is visited with a depth
+ * first search.
+ *
+ * @param insnIndex the index of an instruction of the subroutine.
+ * @param subroutineInsns where the indices of the instructions of the subroutine must be stored.
+ * @param visitedInsns the indices of the instructions that have been visited so far (including in
+ * previous calls to this method). This bitset is updated by this method each time a new
+ * instruction is visited. It is used to make sure each instruction is visited at most once.
+ */
+ private void findReachableInsns(
+ final int insnIndex, final BitSet subroutineInsns, final BitSet visitedInsns) {
+ int currentInsnIndex = insnIndex;
+ // We implicitly assume below that execution can always fall through to the next instruction
+ // after a JSR. But a subroutine may never return, in which case the code after the JSR is
+ // unreachable and can be anything. In particular, it can seem to fall off the end of the
+ // method, so we must handle this case here (we could instead detect whether execution can
+ // return or not from a JSR, but this is more complicated).
+ while (currentInsnIndex < instructions.size()) {
+ // Visit each instruction at most once.
+ if (subroutineInsns.get(currentInsnIndex)) {
+ return;
+ }
+ subroutineInsns.set(currentInsnIndex);
+
+ // Check if this instruction has already been visited by another subroutine.
+ if (visitedInsns.get(currentInsnIndex)) {
+ sharedSubroutineInsns.set(currentInsnIndex);
+ }
+ visitedInsns.set(currentInsnIndex);
+
+ AbstractInsnNode currentInsnNode = instructions.get(currentInsnIndex);
+ if (currentInsnNode.getType() == AbstractInsnNode.JUMP_INSN
+ && currentInsnNode.getOpcode() != JSR) {
+ // Don't follow JSR instructions in the control flow graph.
+ JumpInsnNode jumpInsnNode = (JumpInsnNode) currentInsnNode;
+ findReachableInsns(instructions.indexOf(jumpInsnNode.label), subroutineInsns, visitedInsns);
+ } else if (currentInsnNode.getType() == AbstractInsnNode.TABLESWITCH_INSN) {
+ TableSwitchInsnNode tableSwitchInsnNode = (TableSwitchInsnNode) currentInsnNode;
+ findReachableInsns(
+ instructions.indexOf(tableSwitchInsnNode.dflt), subroutineInsns, visitedInsns);
+ for (LabelNode labelNode : tableSwitchInsnNode.labels) {
+ findReachableInsns(instructions.indexOf(labelNode), subroutineInsns, visitedInsns);
+ }
+ } else if (currentInsnNode.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
+ LookupSwitchInsnNode lookupSwitchInsnNode = (LookupSwitchInsnNode) currentInsnNode;
+ findReachableInsns(
+ instructions.indexOf(lookupSwitchInsnNode.dflt), subroutineInsns, visitedInsns);
+ for (LabelNode labelNode : lookupSwitchInsnNode.labels) {
+ findReachableInsns(instructions.indexOf(labelNode), subroutineInsns, visitedInsns);
+ }
+ }
+
+ // Check if this instruction falls through to the next instruction; if not, return.
+ switch (instructions.get(currentInsnIndex).getOpcode()) {
+ case GOTO:
+ case RET:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case RETURN:
+ case ATHROW:
+ // Note: this either returns from this subroutine, or from a parent subroutine.
+ return;
+ default:
+ // Go to the next instruction.
+ currentInsnIndex++;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Creates the new instructions, inlining each instantiation of each subroutine until the code is
+ * fully elaborated.
+ */
+ private void emitCode() {
+ LinkedList<Instantiation> worklist = new LinkedList<>();
+ // Create an instantiation of the main "subroutine", which is just the main routine.
+ worklist.add(new Instantiation(null, mainSubroutineInsns));
+
+ // Emit instantiations of each subroutine we encounter, including the main subroutine.
+ InsnList newInstructions = new InsnList();
+ List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<>();
+ List<LocalVariableNode> newLocalVariables = new ArrayList<>();
+ while (!worklist.isEmpty()) {
+ Instantiation instantiation = worklist.removeFirst();
+ emitInstantiation(
+ instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
+ }
+ instructions = newInstructions;
+ tryCatchBlocks = newTryCatchBlocks;
+ localVariables = newLocalVariables;
+ }
+
+ /**
+ * Emits an instantiation of a subroutine, specified by <code>instantiation</code>. May add new
+ * instantiations that are invoked by this one to the <code>worklist</code>, and new try/catch
+ * blocks to <code>newTryCatchBlocks</code>.
+ *
+ * @param instantiation the instantiation that must be performed.
+ * @param worklist list of the instantiations that remain to be done.
+ * @param newInstructions the instruction list to which the instantiated code must be appended.
+ * @param newTryCatchBlocks the exception handler list to which the instantiated handlers must be
+ * appended.
+ * @param newLocalVariables the local variables list to which the instantiated local variables
+ * must be appended.
+ */
+ private void emitInstantiation(
+ final Instantiation instantiation,
+ final List<Instantiation> worklist,
+ final InsnList newInstructions,
+ final List<TryCatchBlockNode> newTryCatchBlocks,
+ final List<LocalVariableNode> newLocalVariables) {
+ LabelNode previousLabelNode = null;
+ for (int i = 0; i < instructions.size(); ++i) {
+ AbstractInsnNode insnNode = instructions.get(i);
+ if (insnNode.getType() == AbstractInsnNode.LABEL) {
+ // Always clone all labels, while avoiding to add the same label more than once.
+ LabelNode labelNode = (LabelNode) insnNode;
+ LabelNode clonedLabelNode = instantiation.getClonedLabel(labelNode);
+ if (clonedLabelNode != previousLabelNode) {
+ newInstructions.add(clonedLabelNode);
+ previousLabelNode = clonedLabelNode;
+ }
+ } else if (instantiation.findOwner(i) == instantiation) {
+ // Don't emit instructions that were already emitted by an ancestor subroutine. Note that it
+ // is still possible for a given instruction to be emitted twice because it may belong to
+ // two subroutines that do not invoke each other.
+
+ if (insnNode.getOpcode() == RET) {
+ // Translate RET instruction(s) to a jump to the return label for the appropriate
+ // instantiation. The problem is that the subroutine may "fall through" to the ret of a
+ // parent subroutine; therefore, to find the appropriate ret label we find the oldest
+ // instantiation that claims to own this instruction.
+ LabelNode retLabel = null;
+ for (Instantiation retLabelOwner = instantiation;
+ retLabelOwner != null;
+ retLabelOwner = retLabelOwner.parent) {
+ if (retLabelOwner.subroutineInsns.get(i)) {
+ retLabel = retLabelOwner.returnLabel;
+ }
+ }
+ if (retLabel == null) {
+ // This is only possible if the mainSubroutine owns a RET instruction, which should
+ // never happen for verifiable code.
+ throw new IllegalArgumentException(
+ "Instruction #" + i + " is a RET not owned by any subroutine");
+ }
+ newInstructions.add(new JumpInsnNode(GOTO, retLabel));
+ } else if (insnNode.getOpcode() == JSR) {
+ LabelNode jsrLabelNode = ((JumpInsnNode) insnNode).label;
+ BitSet subroutineInsns = subroutinesInsns.get(jsrLabelNode);
+ Instantiation newInstantiation = new Instantiation(instantiation, subroutineInsns);
+ LabelNode clonedJsrLabelNode = newInstantiation.getClonedLabelForJumpInsn(jsrLabelNode);
+ // Replace the JSR instruction with a GOTO to the instantiated subroutine, and push NULL
+ // for what was once the return address value. This hack allows us to avoid doing any sort
+ // of data flow analysis to figure out which instructions manipulate the old return
+ // address value pointer which is now known to be unneeded.
+ newInstructions.add(new InsnNode(ACONST_NULL));
+ newInstructions.add(new JumpInsnNode(GOTO, clonedJsrLabelNode));
+ newInstructions.add(newInstantiation.returnLabel);
+ // Insert this new instantiation into the queue to be emitted later.
+ worklist.add(newInstantiation);
+ } else {
+ newInstructions.add(insnNode.clone(instantiation));
+ }
+ }
+ }
+
+ // Emit the try/catch blocks that are relevant for this instantiation.
+ for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlocks) {
+ final LabelNode start = instantiation.getClonedLabel(tryCatchBlockNode.start);
+ final LabelNode end = instantiation.getClonedLabel(tryCatchBlockNode.end);
+ if (start != end) {
+ final LabelNode handler =
+ instantiation.getClonedLabelForJumpInsn(tryCatchBlockNode.handler);
+ if (start == null || end == null || handler == null) {
+ throw new AssertionError("Internal error!");
+ }
+ newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, tryCatchBlockNode.type));
+ }
+ }
+
+ // Emit the local variable nodes that are relevant for this instantiation.
+ for (LocalVariableNode localVariableNode : localVariables) {
+ final LabelNode start = instantiation.getClonedLabel(localVariableNode.start);
+ final LabelNode end = instantiation.getClonedLabel(localVariableNode.end);
+ if (start != end) {
+ newLocalVariables.add(
+ new LocalVariableNode(
+ localVariableNode.name,
+ localVariableNode.desc,
+ localVariableNode.signature,
+ start,
+ end,
+ localVariableNode.index));
+ }
+ }
+ }
+
+ /** An instantiation of a subroutine. */
+ private class Instantiation extends AbstractMap<LabelNode, LabelNode> {
+
+ /**
+ * The instantiation from which this one was created (or {@literal null} for the instantiation
+ * of the main "subroutine").
+ */
+ final Instantiation parent;
+
+ /**
+ * The original instructions that belong to the subroutine which is instantiated. Bit i is set
+ * iff instruction at index i belongs to this subroutine.
+ */
+ final BitSet subroutineInsns;
+
+ /**
+ * A map from labels from the original code to labels pointing at code specific to this
+ * instantiation, for use in remapping try/catch blocks, as well as jumps.
+ *
+ * <p>Note that in the presence of instructions belonging to several subroutines, we map the
+ * target label of a GOTO to the label used by the oldest instantiation (parent instantiations
+ * are older than their children). This avoids code duplication during inlining in most cases.
+ */
+ final Map<LabelNode, LabelNode> clonedLabels;
+
+ /** The return label for this instantiation, to which all original returns will be mapped. */
+ final LabelNode returnLabel;
+
+ Instantiation(final Instantiation parent, final BitSet subroutineInsns) {
+ for (Instantiation instantiation = parent;
+ instantiation != null;
+ instantiation = instantiation.parent) {
+ if (instantiation.subroutineInsns == subroutineInsns) {
+ throw new IllegalArgumentException("Recursive invocation of " + subroutineInsns);
+ }
+ }
+
+ this.parent = parent;
+ this.subroutineInsns = subroutineInsns;
+ this.returnLabel = parent == null ? null : new LabelNode();
+ this.clonedLabels = new HashMap<>();
+
+ // Create a clone of each label in the original code of the subroutine. Note that we collapse
+ // labels which point at the same instruction into one.
+ LabelNode clonedLabelNode = null;
+ for (int insnIndex = 0; insnIndex < instructions.size(); insnIndex++) {
+ AbstractInsnNode insnNode = instructions.get(insnIndex);
+ if (insnNode.getType() == AbstractInsnNode.LABEL) {
+ LabelNode labelNode = (LabelNode) insnNode;
+ // If we already have a label pointing at this spot, don't recreate it.
+ if (clonedLabelNode == null) {
+ clonedLabelNode = new LabelNode();
+ }
+ clonedLabels.put(labelNode, clonedLabelNode);
+ } else if (findOwner(insnIndex) == this) {
+ // We will emit this instruction, so clear the duplicateLabelNode flag since the next
+ // Label will refer to a distinct instruction.
+ clonedLabelNode = null;
+ }
+ }
+ }
+
+ /**
+ * Returns the "owner" of a particular instruction relative to this instantiation: the owner
+ * refers to the Instantiation which will emit the version of this instruction that we will
+ * execute.
+ *
+ * <p>Typically, the return value is either <code>this</code> or <code>null</code>. <code>this
+ * </code> indicates that this instantiation will generate the version of this instruction that
+ * we will execute, and <code>null</code> indicates that this instantiation never executes the
+ * given instruction.
+ *
+ * <p>Sometimes, however, an instruction can belong to multiple subroutines; this is called a
+ * shared instruction, and occurs when multiple subroutines branch to common points of control.
+ * In this case, the owner is the oldest instantiation which owns the instruction in question
+ * (parent instantiations are older than their children).
+ *
+ * @param insnIndex the index of an instruction in the original code.
+ * @return the "owner" of a particular instruction relative to this instantiation.
+ */
+ Instantiation findOwner(final int insnIndex) {
+ if (!subroutineInsns.get(insnIndex)) {
+ return null;
+ }
+ if (!sharedSubroutineInsns.get(insnIndex)) {
+ return this;
+ }
+ Instantiation owner = this;
+ for (Instantiation instantiation = parent;
+ instantiation != null;
+ instantiation = instantiation.parent) {
+ if (instantiation.subroutineInsns.get(insnIndex)) {
+ owner = instantiation;
+ }
+ }
+ return owner;
+ }
+
+ /**
+ * Returns the clone of the given original label that is appropriate for use in a jump
+ * instruction.
+ *
+ * @param labelNode a label of the original code.
+ * @return a clone of the given label for use in a jump instruction in the inlined code.
+ */
+ LabelNode getClonedLabelForJumpInsn(final LabelNode labelNode) {
+ // findOwner should never return null, because owner is null only if an instruction cannot be
+ // reached from this subroutine.
+ return findOwner(instructions.indexOf(labelNode)).clonedLabels.get(labelNode);
+ }
+
+ /**
+ * Returns the clone of the given original label that is appropriate for use by a try/catch
+ * block or a variable annotation.
+ *
+ * @param labelNode a label of the original code.
+ * @return a clone of the given label for use by a try/catch block or a variable annotation in
+ * the inlined code.
+ */
+ LabelNode getClonedLabel(final LabelNode labelNode) {
+ return clonedLabels.get(labelNode);
+ }
+
+ // AbstractMap implementation
+
+ @Override
+ public Set<Map.Entry<LabelNode, LabelNode>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LabelNode get(final Object key) {
+ return getClonedLabelForJumpInsn((LabelNode) key);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java
new file mode 100644
index 00000000..92d542b8
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java
@@ -0,0 +1,351 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link MethodVisitor} that renumbers local variables in their order of appearance. This adapter
+ * allows one to easily add new local variables to a method. It may be used by inheriting from this
+ * class, but the preferred way of using it is via delegation: the next visitor in the chain can
+ * indeed add new locals when needed by calling {@link #newLocal} on this adapter (this requires a
+ * reference back to this {@link LocalVariablesSorter}).
+ *
+ * @author Chris Nokleberg
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+public class LocalVariablesSorter extends MethodVisitor {
+
+ /** The type of the java.lang.Object class. */
+ private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
+
+ /**
+ * The mapping from old to new local variable indices. A local variable at index i of size 1 is
+ * remapped to 'mapping[2*i]', while a local variable at index i of size 2 is remapped to
+ * 'mapping[2*i+1]'.
+ */
+ private int[] remappedVariableIndices = new int[40];
+
+ /**
+ * The local variable types after remapping. The format of this array is the same as in {@link
+ * MethodVisitor#visitFrame}, except that long and double types use two slots.
+ */
+ private Object[] remappedLocalTypes = new Object[20];
+
+ /** The index of the first local variable, after formal parameters. */
+ protected final int firstLocal;
+
+ /** The index of the next local variable to be created by {@link #newLocal}. */
+ protected int nextLocal;
+
+ /**
+ * Constructs a new {@link LocalVariablesSorter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #LocalVariablesSorter(int, int, String, MethodVisitor)}
+ * version.
+ *
+ * @param access access flags of the adapted method.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ * @throws IllegalStateException if a subclass calls this constructor.
+ */
+ public LocalVariablesSorter(
+ final int access, final String descriptor, final MethodVisitor methodVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, access, descriptor, methodVisitor);
+ if (getClass() != LocalVariablesSorter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link LocalVariablesSorter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param access access flags of the adapted method.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter delegates calls.
+ */
+ protected LocalVariablesSorter(
+ final int api, final int access, final String descriptor, final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
+ for (Type argumentType : Type.getArgumentTypes(descriptor)) {
+ nextLocal += argumentType.getSize();
+ }
+ firstLocal = nextLocal;
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ Type varType;
+ switch (opcode) {
+ case Opcodes.LLOAD:
+ case Opcodes.LSTORE:
+ varType = Type.LONG_TYPE;
+ break;
+ case Opcodes.DLOAD:
+ case Opcodes.DSTORE:
+ varType = Type.DOUBLE_TYPE;
+ break;
+ case Opcodes.FLOAD:
+ case Opcodes.FSTORE:
+ varType = Type.FLOAT_TYPE;
+ break;
+ case Opcodes.ILOAD:
+ case Opcodes.ISTORE:
+ varType = Type.INT_TYPE;
+ break;
+ case Opcodes.ALOAD:
+ case Opcodes.ASTORE:
+ case Opcodes.RET:
+ varType = OBJECT_TYPE;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid opcode " + opcode);
+ }
+ super.visitVarInsn(opcode, remap(varIndex, varType));
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ super.visitIincInsn(remap(varIndex, Type.INT_TYPE), increment);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ super.visitMaxs(maxStack, nextLocal);
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ int remappedIndex = remap(index, Type.getType(descriptor));
+ super.visitLocalVariable(name, descriptor, signature, start, end, remappedIndex);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ Type type = Type.getType(descriptor);
+ int[] remappedIndex = new int[index.length];
+ for (int i = 0; i < remappedIndex.length; ++i) {
+ remappedIndex[i] = remap(index[i], type);
+ }
+ return super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, remappedIndex, descriptor, visible);
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ if (type != Opcodes.F_NEW) { // Uncompressed frame.
+ throw new IllegalArgumentException(
+ "LocalVariablesSorter only accepts expanded frames (see ClassReader.EXPAND_FRAMES)");
+ }
+
+ // Create a copy of remappedLocals.
+ Object[] oldRemappedLocals = new Object[remappedLocalTypes.length];
+ System.arraycopy(remappedLocalTypes, 0, oldRemappedLocals, 0, oldRemappedLocals.length);
+
+ updateNewLocals(remappedLocalTypes);
+
+ // Copy the types from 'local' to 'remappedLocals'. 'remappedLocals' already contains the
+ // variables added with 'newLocal'.
+ int oldVar = 0; // Old local variable index.
+ for (int i = 0; i < numLocal; ++i) {
+ Object localType = local[i];
+ if (localType != Opcodes.TOP) {
+ Type varType = OBJECT_TYPE;
+ if (localType == Opcodes.INTEGER) {
+ varType = Type.INT_TYPE;
+ } else if (localType == Opcodes.FLOAT) {
+ varType = Type.FLOAT_TYPE;
+ } else if (localType == Opcodes.LONG) {
+ varType = Type.LONG_TYPE;
+ } else if (localType == Opcodes.DOUBLE) {
+ varType = Type.DOUBLE_TYPE;
+ } else if (localType instanceof String) {
+ varType = Type.getObjectType((String) localType);
+ }
+ setFrameLocal(remap(oldVar, varType), localType);
+ }
+ oldVar += localType == Opcodes.LONG || localType == Opcodes.DOUBLE ? 2 : 1;
+ }
+
+ // Remove TOP after long and double types as well as trailing TOPs.
+ oldVar = 0;
+ int newVar = 0;
+ int remappedNumLocal = 0;
+ while (oldVar < remappedLocalTypes.length) {
+ Object localType = remappedLocalTypes[oldVar];
+ oldVar += localType == Opcodes.LONG || localType == Opcodes.DOUBLE ? 2 : 1;
+ if (localType != null && localType != Opcodes.TOP) {
+ remappedLocalTypes[newVar++] = localType;
+ remappedNumLocal = newVar;
+ } else {
+ remappedLocalTypes[newVar++] = Opcodes.TOP;
+ }
+ }
+
+ // Visit the remapped frame.
+ super.visitFrame(type, remappedNumLocal, remappedLocalTypes, numStack, stack);
+
+ // Restore the original value of 'remappedLocals'.
+ remappedLocalTypes = oldRemappedLocals;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new local variable of the given type.
+ *
+ * @param type the type of the local variable to be created.
+ * @return the identifier of the newly created local variable.
+ */
+ public int newLocal(final Type type) {
+ Object localType;
+ switch (type.getSort()) {
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ localType = Opcodes.INTEGER;
+ break;
+ case Type.FLOAT:
+ localType = Opcodes.FLOAT;
+ break;
+ case Type.LONG:
+ localType = Opcodes.LONG;
+ break;
+ case Type.DOUBLE:
+ localType = Opcodes.DOUBLE;
+ break;
+ case Type.ARRAY:
+ localType = type.getDescriptor();
+ break;
+ case Type.OBJECT:
+ localType = type.getInternalName();
+ break;
+ default:
+ throw new AssertionError();
+ }
+ int local = newLocalMapping(type);
+ setLocalType(local, type);
+ setFrameLocal(local, localType);
+ return local;
+ }
+
+ /**
+ * Notifies subclasses that a new stack map frame is being visited. The array argument contains
+ * the stack map frame types corresponding to the local variables added with {@link #newLocal}.
+ * This method can update these types in place for the stack map frame being visited. The default
+ * implementation of this method does nothing, i.e. a local variable added with {@link #newLocal}
+ * will have the same type in all stack map frames. But this behavior is not always the desired
+ * one, for instance if a local variable is added in the middle of a try/catch block: the frame
+ * for the exception handler should have a TOP type for this new local.
+ *
+ * @param newLocals the stack map frame types corresponding to the local variables added with
+ * {@link #newLocal} (and null for the others). The format of this array is the same as in
+ * {@link MethodVisitor#visitFrame}, except that long and double types use two slots. The
+ * types for the current stack map frame must be updated in place in this array.
+ */
+ protected void updateNewLocals(final Object[] newLocals) {
+ // The default implementation does nothing.
+ }
+
+ /**
+ * Notifies subclasses that a local variable has been added or remapped. The default
+ * implementation of this method does nothing.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal}.
+ * @param type the type of the value being stored in the local variable.
+ */
+ protected void setLocalType(final int local, final Type type) {
+ // The default implementation does nothing.
+ }
+
+ private void setFrameLocal(final int local, final Object type) {
+ int numLocals = remappedLocalTypes.length;
+ if (local >= numLocals) {
+ Object[] newRemappedLocalTypes = new Object[Math.max(2 * numLocals, local + 1)];
+ System.arraycopy(remappedLocalTypes, 0, newRemappedLocalTypes, 0, numLocals);
+ remappedLocalTypes = newRemappedLocalTypes;
+ }
+ remappedLocalTypes[local] = type;
+ }
+
+ private int remap(final int varIndex, final Type type) {
+ if (varIndex + type.getSize() <= firstLocal) {
+ return varIndex;
+ }
+ int key = 2 * varIndex + type.getSize() - 1;
+ int size = remappedVariableIndices.length;
+ if (key >= size) {
+ int[] newRemappedVariableIndices = new int[Math.max(2 * size, key + 1)];
+ System.arraycopy(remappedVariableIndices, 0, newRemappedVariableIndices, 0, size);
+ remappedVariableIndices = newRemappedVariableIndices;
+ }
+ int value = remappedVariableIndices[key];
+ if (value == 0) {
+ value = newLocalMapping(type);
+ setLocalType(value, type);
+ remappedVariableIndices[key] = value + 1;
+ } else {
+ value--;
+ }
+ return value;
+ }
+
+ protected int newLocalMapping(final Type type) {
+ int local = nextLocal;
+ nextLocal += type.getSize();
+ return local;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java
new file mode 100644
index 00000000..5b6d0443
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Method.java
@@ -0,0 +1,262 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.objectweb.asm.Type;
+
+/**
+ * A named method descriptor.
+ *
+ * @author Juozas Baliuka
+ * @author Chris Nokleberg
+ * @author Eric Bruneton
+ */
+public class Method {
+
+ /** The method name. */
+ private final String name;
+
+ /** The method descriptor. */
+ private final String descriptor;
+
+ /** The descriptors of the primitive Java types (plus void). */
+ private static final Map<String, String> PRIMITIVE_TYPE_DESCRIPTORS;
+
+ static {
+ HashMap<String, String> descriptors = new HashMap<>();
+ descriptors.put("void", "V");
+ descriptors.put("byte", "B");
+ descriptors.put("char", "C");
+ descriptors.put("double", "D");
+ descriptors.put("float", "F");
+ descriptors.put("int", "I");
+ descriptors.put("long", "J");
+ descriptors.put("short", "S");
+ descriptors.put("boolean", "Z");
+ PRIMITIVE_TYPE_DESCRIPTORS = descriptors;
+ }
+
+ /**
+ * Constructs a new {@link Method}.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor.
+ */
+ public Method(final String name, final String descriptor) {
+ this.name = name;
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * Constructs a new {@link Method}.
+ *
+ * @param name the method's name.
+ * @param returnType the method's return type.
+ * @param argumentTypes the method's argument types.
+ */
+ public Method(final String name, final Type returnType, final Type[] argumentTypes) {
+ this(name, Type.getMethodDescriptor(returnType, argumentTypes));
+ }
+
+ /**
+ * Creates a new {@link Method}.
+ *
+ * @param method a java.lang.reflect method descriptor
+ * @return a {@link Method} corresponding to the given Java method declaration.
+ */
+ public static Method getMethod(final java.lang.reflect.Method method) {
+ return new Method(method.getName(), Type.getMethodDescriptor(method));
+ }
+
+ /**
+ * Creates a new {@link Method}.
+ *
+ * @param constructor a java.lang.reflect constructor descriptor
+ * @return a {@link Method} corresponding to the given Java constructor declaration.
+ */
+ public static Method getMethod(final java.lang.reflect.Constructor<?> constructor) {
+ return new Method("<init>", Type.getConstructorDescriptor(constructor));
+ }
+
+ /**
+ * Returns a {@link Method} corresponding to the given Java method declaration.
+ *
+ * @param method a Java method declaration, without argument names, of the form "returnType name
+ * (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int",
+ * "float", "java.util.List", ...). Classes of the java.lang package can be specified by their
+ * unqualified name; all other classes names must be fully qualified.
+ * @return a {@link Method} corresponding to the given Java method declaration.
+ * @throws IllegalArgumentException if <code>method</code> could not get parsed.
+ */
+ public static Method getMethod(final String method) {
+ return getMethod(method, false);
+ }
+
+ /**
+ * Returns a {@link Method} corresponding to the given Java method declaration.
+ *
+ * @param method a Java method declaration, without argument names, of the form "returnType name
+ * (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int",
+ * "float", "java.util.List", ...). Classes of the java.lang package may be specified by their
+ * unqualified name, depending on the defaultPackage argument; all other classes names must be
+ * fully qualified.
+ * @param defaultPackage true if unqualified class names belong to the default package, or false
+ * if they correspond to java.lang classes. For instance "Object" means "Object" if this
+ * option is true, or "java.lang.Object" otherwise.
+ * @return a {@link Method} corresponding to the given Java method declaration.
+ * @throws IllegalArgumentException if <code>method</code> could not get parsed.
+ */
+ public static Method getMethod(final String method, final boolean defaultPackage) {
+ final int spaceIndex = method.indexOf(' ');
+ int currentArgumentStartIndex = method.indexOf('(', spaceIndex) + 1;
+ final int endIndex = method.indexOf(')', currentArgumentStartIndex);
+ if (spaceIndex == -1 || currentArgumentStartIndex == 0 || endIndex == -1) {
+ throw new IllegalArgumentException();
+ }
+ final String returnType = method.substring(0, spaceIndex);
+ final String methodName =
+ method.substring(spaceIndex + 1, currentArgumentStartIndex - 1).trim();
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append('(');
+ int currentArgumentEndIndex;
+ do {
+ String argumentDescriptor;
+ currentArgumentEndIndex = method.indexOf(',', currentArgumentStartIndex);
+ if (currentArgumentEndIndex == -1) {
+ argumentDescriptor =
+ getDescriptorInternal(
+ method.substring(currentArgumentStartIndex, endIndex).trim(), defaultPackage);
+ } else {
+ argumentDescriptor =
+ getDescriptorInternal(
+ method.substring(currentArgumentStartIndex, currentArgumentEndIndex).trim(),
+ defaultPackage);
+ currentArgumentStartIndex = currentArgumentEndIndex + 1;
+ }
+ stringBuilder.append(argumentDescriptor);
+ } while (currentArgumentEndIndex != -1);
+ stringBuilder.append(')').append(getDescriptorInternal(returnType, defaultPackage));
+ return new Method(methodName, stringBuilder.toString());
+ }
+
+ /**
+ * Returns the descriptor corresponding to the given type name.
+ *
+ * @param type a Java type name.
+ * @param defaultPackage true if unqualified class names belong to the default package, or false
+ * if they correspond to java.lang classes. For instance "Object" means "Object" if this
+ * option is true, or "java.lang.Object" otherwise.
+ * @return the descriptor corresponding to the given type name.
+ */
+ private static String getDescriptorInternal(final String type, final boolean defaultPackage) {
+ if ("".equals(type)) {
+ return type;
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ int arrayBracketsIndex = 0;
+ while ((arrayBracketsIndex = type.indexOf("[]", arrayBracketsIndex) + 1) > 0) {
+ stringBuilder.append('[');
+ }
+
+ String elementType = type.substring(0, type.length() - stringBuilder.length() * 2);
+ String descriptor = PRIMITIVE_TYPE_DESCRIPTORS.get(elementType);
+ if (descriptor != null) {
+ stringBuilder.append(descriptor);
+ } else {
+ stringBuilder.append('L');
+ if (elementType.indexOf('.') < 0) {
+ if (!defaultPackage) {
+ stringBuilder.append("java/lang/");
+ }
+ stringBuilder.append(elementType);
+ } else {
+ stringBuilder.append(elementType.replace('.', '/'));
+ }
+ stringBuilder.append(';');
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Returns the name of the method described by this object.
+ *
+ * @return the name of the method described by this object.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the descriptor of the method described by this object.
+ *
+ * @return the descriptor of the method described by this object.
+ */
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the return type of the method described by this object.
+ *
+ * @return the return type of the method described by this object.
+ */
+ public Type getReturnType() {
+ return Type.getReturnType(descriptor);
+ }
+
+ /**
+ * Returns the argument types of the method described by this object.
+ *
+ * @return the argument types of the method described by this object.
+ */
+ public Type[] getArgumentTypes() {
+ return Type.getArgumentTypes(descriptor);
+ }
+
+ @Override
+ public String toString() {
+ return name + descriptor;
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (!(other instanceof Method)) {
+ return false;
+ }
+ Method otherMethod = (Method) other;
+ return name.equals(otherMethod.name) && descriptor.equals(otherMethod.descriptor);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode() ^ descriptor.hashCode();
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java
new file mode 100644
index 00000000..7bc9f7a9
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java
@@ -0,0 +1,290 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link MethodVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Eugene Kuleshov
+ */
+public class MethodRemapper extends MethodVisitor {
+
+ /** The remapper used to remap the types in the visited field. */
+ protected final Remapper remapper;
+
+ /**
+ * Constructs a new {@link MethodRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #MethodRemapper(int,MethodVisitor,Remapper)} version.
+ *
+ * @param methodVisitor the method visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited method.
+ */
+ public MethodRemapper(final MethodVisitor methodVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, methodVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link MethodRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited method.
+ */
+ protected MethodRemapper(
+ final int api, final MethodVisitor methodVisitor, final Remapper remapper) {
+ super(api, methodVisitor);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ AnnotationVisitor annotationVisitor = super.visitAnnotationDefault();
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(/* descriptor = */ null, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitAnnotation(remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitParameterAnnotation(parameter, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ super.visitFrame(
+ type,
+ numLocal,
+ remapFrameTypes(numLocal, local),
+ numStack,
+ remapFrameTypes(numStack, stack));
+ }
+
+ private Object[] remapFrameTypes(final int numTypes, final Object[] frameTypes) {
+ if (frameTypes == null) {
+ return frameTypes;
+ }
+ Object[] remappedFrameTypes = null;
+ for (int i = 0; i < numTypes; ++i) {
+ if (frameTypes[i] instanceof String) {
+ if (remappedFrameTypes == null) {
+ remappedFrameTypes = new Object[numTypes];
+ System.arraycopy(frameTypes, 0, remappedFrameTypes, 0, numTypes);
+ }
+ remappedFrameTypes[i] = remapper.mapType((String) frameTypes[i]);
+ }
+ }
+ return remappedFrameTypes == null ? frameTypes : remappedFrameTypes;
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitFieldInsn(
+ opcode,
+ remapper.mapType(owner),
+ remapper.mapFieldName(owner, name, descriptor),
+ remapper.mapDesc(descriptor));
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ super.visitMethodInsn(
+ opcodeAndSource,
+ remapper.mapType(owner),
+ remapper.mapMethodName(owner, name, descriptor),
+ remapper.mapMethodDesc(descriptor),
+ isInterface);
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArguments.length];
+ for (int i = 0; i < bootstrapMethodArguments.length; ++i) {
+ remappedBootstrapMethodArguments[i] = remapper.mapValue(bootstrapMethodArguments[i]);
+ }
+ super.visitInvokeDynamicInsn(
+ remapper.mapInvokeDynamicMethodName(name, descriptor),
+ remapper.mapMethodDesc(descriptor),
+ (Handle) remapper.mapValue(bootstrapMethodHandle),
+ remappedBootstrapMethodArguments);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ super.visitTypeInsn(opcode, remapper.mapType(type));
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ super.visitLdcInsn(remapper.mapValue(value));
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ super.visitMultiANewArrayInsn(remapper.mapDesc(descriptor), numDimensions);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitInsnAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ super.visitTryCatchBlock(start, end, handler, type == null ? null : remapper.mapType(type));
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitTryCatchAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ super.visitLocalVariable(
+ name,
+ remapper.mapDesc(descriptor),
+ remapper.mapSignature(signature, true),
+ start,
+ end,
+ index);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? annotationVisitor
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead.
+ */
+ @Deprecated
+ protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param descriptor the descriptor of the visited annotation.
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected AnnotationVisitor createAnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper)
+ .orDeprecatedValue(createAnnotationRemapper(annotationVisitor));
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleHashesAttribute.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleHashesAttribute.java
new file mode 100644
index 00000000..817ef37c
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleHashesAttribute.java
@@ -0,0 +1,139 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A ModuleHashes attribute. This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleHashesAttribute extends Attribute {
+
+ /** The name of the hashing algorithm. */
+ public String algorithm;
+
+ /** A list of module names. */
+ public List<String> modules;
+
+ /** The hash of the modules in {@link #modules}. The two lists must have the same size. */
+ public List<byte[]> hashes;
+
+ /**
+ * Constructs a new {@link ModuleHashesAttribute}.
+ *
+ * @param algorithm the name of the hashing algorithm.
+ * @param modules a list of module names.
+ * @param hashes the hash of the modules in 'modules'. The two lists must have the same size.
+ */
+ public ModuleHashesAttribute(
+ final String algorithm, final List<String> modules, final List<byte[]> hashes) {
+ super("ModuleHashes");
+ this.algorithm = algorithm;
+ this.modules = modules;
+ this.hashes = hashes;
+ }
+
+ /**
+ * Constructs an empty {@link ModuleHashesAttribute}. This object can be passed as a prototype to
+ * the {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)} method.
+ */
+ public ModuleHashesAttribute() {
+ this(null, null, null);
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ int currentOffset = offset;
+
+ String hashAlgorithm = classReader.readUTF8(currentOffset, charBuffer);
+ currentOffset += 2;
+
+ int numModules = classReader.readUnsignedShort(currentOffset);
+ currentOffset += 2;
+
+ ArrayList<String> moduleList = new ArrayList<>(numModules);
+ ArrayList<byte[]> hashList = new ArrayList<>(numModules);
+
+ for (int i = 0; i < numModules; ++i) {
+ String module = classReader.readModule(currentOffset, charBuffer);
+ currentOffset += 2;
+ moduleList.add(module);
+
+ int hashLength = classReader.readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ byte[] hash = new byte[hashLength];
+ for (int j = 0; j < hashLength; ++j) {
+ hash[j] = (byte) classReader.readByte(currentOffset);
+ currentOffset += 1;
+ }
+ hashList.add(hash);
+ }
+ return new ModuleHashesAttribute(hashAlgorithm, moduleList, hashList);
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ ByteVector byteVector = new ByteVector();
+ byteVector.putShort(classWriter.newUTF8(algorithm));
+ if (modules == null) {
+ byteVector.putShort(0);
+ } else {
+ int numModules = modules.size();
+ byteVector.putShort(numModules);
+ for (int i = 0; i < numModules; ++i) {
+ String module = modules.get(i);
+ byte[] hash = hashes.get(i);
+ byteVector
+ .putShort(classWriter.newModule(module))
+ .putShort(hash.length)
+ .putByteArray(hash, 0, hash.length);
+ }
+ }
+ return byteVector;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java
new file mode 100644
index 00000000..926a4f95
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java
@@ -0,0 +1,121 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRemapper extends ModuleVisitor {
+
+ /** The remapper used to remap the types in the visited module. */
+ protected final Remapper remapper;
+
+ /**
+ * Constructs a new {@link ModuleRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #ModuleRemapper(int,ModuleVisitor,Remapper)} version.
+ *
+ * @param moduleVisitor the module visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited module.
+ */
+ public ModuleRemapper(final ModuleVisitor moduleVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, moduleVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link ModuleRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param moduleVisitor the module visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited module.
+ */
+ protected ModuleRemapper(
+ final int api, final ModuleVisitor moduleVisitor, final Remapper remapper) {
+ super(api, moduleVisitor);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ super.visitMainClass(remapper.mapType(mainClass));
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ super.visitPackage(remapper.mapPackageName(packaze));
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ super.visitRequire(remapper.mapModuleName(module), access, version);
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ String[] remappedModules = null;
+ if (modules != null) {
+ remappedModules = new String[modules.length];
+ for (int i = 0; i < modules.length; ++i) {
+ remappedModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitExport(remapper.mapPackageName(packaze), access, remappedModules);
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ String[] remappedModules = null;
+ if (modules != null) {
+ remappedModules = new String[modules.length];
+ for (int i = 0; i < modules.length; ++i) {
+ remappedModules[i] = remapper.mapModuleName(modules[i]);
+ }
+ }
+ super.visitOpen(remapper.mapPackageName(packaze), access, remappedModules);
+ }
+
+ @Override
+ public void visitUse(final String service) {
+ super.visitUse(remapper.mapType(service));
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ String[] remappedProviders = new String[providers.length];
+ for (int i = 0; i < providers.length; ++i) {
+ remappedProviders[i] = remapper.mapType(providers[i]);
+ }
+ super.visitProvide(remapper.mapType(service), remappedProviders);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleResolutionAttribute.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleResolutionAttribute.java
new file mode 100644
index 00000000..6f4a3da5
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleResolutionAttribute.java
@@ -0,0 +1,113 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A ModuleResolution attribute. This attribute is specific to the OpenJDK and may change in the
+ * future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleResolutionAttribute extends Attribute {
+ /**
+ * The resolution state of a module meaning that the module is not available from the class-path
+ * by default.
+ */
+ public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
+
+ /** The resolution state of a module meaning the module is marked as deprecated. */
+ public static final int RESOLUTION_WARN_DEPRECATED = 2;
+
+ /**
+ * The resolution state of a module meaning the module is marked as deprecated and will be removed
+ * in a future release.
+ */
+ public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
+
+ /**
+ * The resolution state of a module meaning the module is not yet standardized, so in incubating
+ * mode.
+ */
+ public static final int RESOLUTION_WARN_INCUBATING = 8;
+
+ /**
+ * The resolution state of the module. Must be one of {@link #RESOLUTION_WARN_DEPRECATED}, {@link
+ * #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and {@link #RESOLUTION_WARN_INCUBATING}.
+ */
+ public int resolution;
+
+ /**
+ * Constructs a new {@link ModuleResolutionAttribute}.
+ *
+ * @param resolution the resolution state of the module. Must be one of {@link
+ * #RESOLUTION_WARN_DEPRECATED}, {@link #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and {@link
+ * #RESOLUTION_WARN_INCUBATING}.
+ */
+ public ModuleResolutionAttribute(final int resolution) {
+ super("ModuleResolution");
+ this.resolution = resolution;
+ }
+
+ /**
+ * Constructs an empty {@link ModuleResolutionAttribute}. This object can be passed as a prototype
+ * to the {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)} method.
+ */
+ public ModuleResolutionAttribute() {
+ this(0);
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeOffset,
+ final Label[] labels) {
+ return new ModuleResolutionAttribute(classReader.readUnsignedShort(offset));
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ ByteVector byteVector = new ByteVector();
+ byteVector.putShort(resolution);
+ return byteVector;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleTargetAttribute.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleTargetAttribute.java
new file mode 100644
index 00000000..2457b7e6
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleTargetAttribute.java
@@ -0,0 +1,87 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A ModuleTarget attribute. This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleTargetAttribute extends Attribute {
+
+ /** The name of the platform on which the module can run. */
+ public String platform;
+
+ /**
+ * Constructs a new {@link ModuleTargetAttribute}.
+ *
+ * @param platform the name of the platform on which the module can run.
+ */
+ public ModuleTargetAttribute(final String platform) {
+ super("ModuleTarget");
+ this.platform = platform;
+ }
+
+ /**
+ * Constructs an empty {@link ModuleTargetAttribute}. This object can be passed as a prototype to
+ * the {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)} method.
+ */
+ public ModuleTargetAttribute() {
+ this(null);
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeOffset,
+ final Label[] labels) {
+ return new ModuleTargetAttribute(classReader.readUTF8(offset, charBuffer));
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ ByteVector byteVector = new ByteVector();
+ byteVector.putShort(platform == null ? 0 : classWriter.newUTF8(platform));
+ return byteVector;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java
new file mode 100644
index 00000000..2f1e5ae2
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/RecordComponentRemapper.java
@@ -0,0 +1,118 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link RecordComponentVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Remi Forax
+ */
+public class RecordComponentRemapper extends RecordComponentVisitor {
+
+ /** The remapper used to remap the types in the visited field. */
+ protected final Remapper remapper;
+
+ /**
+ * Constructs a new {@link RecordComponentRemapper}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link
+ * #RecordComponentRemapper(int,RecordComponentVisitor,Remapper)} version.
+ *
+ * @param recordComponentVisitor the record component visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited record component.
+ */
+ public RecordComponentRemapper(
+ final RecordComponentVisitor recordComponentVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, recordComponentVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link RecordComponentRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of {@link
+ * org.objectweb.asm.Opcodes#ASM8} or {@link org.objectweb.asm.Opcodes#ASM9}.
+ * @param recordComponentVisitor the record component visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited record component.
+ */
+ protected RecordComponentRemapper(
+ final int api, final RecordComponentVisitor recordComponentVisitor, final Remapper remapper) {
+ super(api, recordComponentVisitor);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitAnnotation(remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ AnnotationVisitor annotationVisitor =
+ super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
+ return annotationVisitor == null
+ ? null
+ : createAnnotationRemapper(descriptor, annotationVisitor);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createAnnotationRemapper(String, AnnotationVisitor)} instead.
+ */
+ @Deprecated
+ protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, /* descriptor = */ null, annotationVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new remapper for annotations. The default implementation of this method returns a
+ * new {@link AnnotationRemapper}.
+ *
+ * @param descriptor the descriptor sof the visited annotation.
+ * @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected AnnotationVisitor createAnnotationRemapper(
+ final String descriptor, final AnnotationVisitor annotationVisitor) {
+ return new AnnotationRemapper(api, descriptor, annotationVisitor, remapper)
+ .orDeprecatedValue(createAnnotationRemapper(annotationVisitor));
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java
new file mode 100644
index 00000000..3004b4d2
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/Remapper.java
@@ -0,0 +1,385 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+import org.objectweb.asm.signature.SignatureWriter;
+
+/**
+ * A class responsible for remapping types and names.
+ *
+ * @author Eugene Kuleshov
+ */
+public abstract class Remapper {
+
+ /**
+ * Returns the given descriptor, remapped with {@link #map(String)}.
+ *
+ * @param descriptor a type descriptor.
+ * @return the given descriptor, with its [array element type] internal name remapped with {@link
+ * #map(String)} (if the descriptor corresponds to an array or object type, otherwise the
+ * descriptor is returned as is). See {@link Type#getInternalName()}.
+ */
+ public String mapDesc(final String descriptor) {
+ return mapType(Type.getType(descriptor)).getDescriptor();
+ }
+
+ /**
+ * Returns the given {@link Type}, remapped with {@link #map(String)} or {@link
+ * #mapMethodDesc(String)}.
+ *
+ * @param type a type, which can be a method type.
+ * @return the given type, with its [array element type] internal name remapped with {@link
+ * #map(String)} (if the type is an array or object type, otherwise the type is returned as
+ * is) or, of the type is a method type, with its descriptor remapped with {@link
+ * #mapMethodDesc(String)}. See {@link Type#getInternalName()}.
+ */
+ private Type mapType(final Type type) {
+ switch (type.getSort()) {
+ case Type.ARRAY:
+ StringBuilder remappedDescriptor = new StringBuilder();
+ for (int i = 0; i < type.getDimensions(); ++i) {
+ remappedDescriptor.append('[');
+ }
+ remappedDescriptor.append(mapType(type.getElementType()).getDescriptor());
+ return Type.getType(remappedDescriptor.toString());
+ case Type.OBJECT:
+ String remappedInternalName = map(type.getInternalName());
+ return remappedInternalName != null ? Type.getObjectType(remappedInternalName) : type;
+ case Type.METHOD:
+ return Type.getMethodType(mapMethodDesc(type.getDescriptor()));
+ default:
+ return type;
+ }
+ }
+
+ /**
+ * Returns the given internal name, remapped with {@link #map(String)}.
+ *
+ * @param internalName the internal name (or array type descriptor) of some (array) class (see
+ * {@link Type#getInternalName()}).
+ * @return the given internal name, remapped with {@link #map(String)} (see {@link
+ * Type#getInternalName()}).
+ */
+ public String mapType(final String internalName) {
+ if (internalName == null) {
+ return null;
+ }
+ return mapType(Type.getObjectType(internalName)).getInternalName();
+ }
+
+ /**
+ * Returns the given internal names, remapped with {@link #map(String)}.
+ *
+ * @param internalNames the internal names (or array type descriptors) of some (array) classes
+ * (see {@link Type#getInternalName()}).
+ * @return the given internal name, remapped with {@link #map(String)} (see {@link
+ * Type#getInternalName()}).
+ */
+ public String[] mapTypes(final String[] internalNames) {
+ String[] remappedInternalNames = null;
+ for (int i = 0; i < internalNames.length; ++i) {
+ String internalName = internalNames[i];
+ String remappedInternalName = mapType(internalName);
+ if (remappedInternalName != null) {
+ if (remappedInternalNames == null) {
+ remappedInternalNames = internalNames.clone();
+ }
+ remappedInternalNames[i] = remappedInternalName;
+ }
+ }
+ return remappedInternalNames != null ? remappedInternalNames : internalNames;
+ }
+
+ /**
+ * Returns the given method descriptor, with its argument and return type descriptors remapped
+ * with {@link #mapDesc(String)}.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the given method descriptor, with its argument and return type descriptors remapped
+ * with {@link #mapDesc(String)}.
+ */
+ public String mapMethodDesc(final String methodDescriptor) {
+ if ("()V".equals(methodDescriptor)) {
+ return methodDescriptor;
+ }
+
+ StringBuilder stringBuilder = new StringBuilder("(");
+ for (Type argumentType : Type.getArgumentTypes(methodDescriptor)) {
+ stringBuilder.append(mapType(argumentType).getDescriptor());
+ }
+ Type returnType = Type.getReturnType(methodDescriptor);
+ if (returnType == Type.VOID_TYPE) {
+ stringBuilder.append(")V");
+ } else {
+ stringBuilder.append(')').append(mapType(returnType).getDescriptor());
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Returns the given value, remapped with this remapper. Possible values are {@link Boolean},
+ * {@link Byte}, {@link Short}, {@link Character}, {@link Integer}, {@link Long}, {@link Double},
+ * {@link Float}, {@link String}, {@link Type}, {@link Handle}, {@link ConstantDynamic} or arrays
+ * of primitive types .
+ *
+ * @param value an object. Only {@link Type}, {@link Handle} and {@link ConstantDynamic} values
+ * are remapped.
+ * @return the given value, remapped with this remapper.
+ */
+ public Object mapValue(final Object value) {
+ if (value instanceof Type) {
+ return mapType((Type) value);
+ }
+ if (value instanceof Handle) {
+ Handle handle = (Handle) value;
+ boolean isFieldHandle = handle.getTag() <= Opcodes.H_PUTSTATIC;
+
+ return new Handle(
+ handle.getTag(),
+ mapType(handle.getOwner()),
+ isFieldHandle
+ ? mapFieldName(handle.getOwner(), handle.getName(), handle.getDesc())
+ : mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()),
+ isFieldHandle ? mapDesc(handle.getDesc()) : mapMethodDesc(handle.getDesc()),
+ handle.isInterface());
+ }
+ if (value instanceof ConstantDynamic) {
+ ConstantDynamic constantDynamic = (ConstantDynamic) value;
+ int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
+ Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArgumentCount];
+ for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
+ remappedBootstrapMethodArguments[i] =
+ mapValue(constantDynamic.getBootstrapMethodArgument(i));
+ }
+ String descriptor = constantDynamic.getDescriptor();
+ return new ConstantDynamic(
+ mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor),
+ mapDesc(descriptor),
+ (Handle) mapValue(constantDynamic.getBootstrapMethod()),
+ remappedBootstrapMethodArguments);
+ }
+ return value;
+ }
+
+ /**
+ * Returns the given signature, remapped with the {@link SignatureVisitor} returned by {@link
+ * #createSignatureRemapper(SignatureVisitor)}.
+ *
+ * @param signature a <i>JavaTypeSignature</i>, <i>ClassSignature</i> or <i>MethodSignature</i>.
+ * @param typeSignature whether the given signature is a <i>JavaTypeSignature</i>.
+ * @return signature the given signature, remapped with the {@link SignatureVisitor} returned by
+ * {@link #createSignatureRemapper(SignatureVisitor)}.
+ */
+ public String mapSignature(final String signature, final boolean typeSignature) {
+ if (signature == null) {
+ return null;
+ }
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureWriter signatureWriter = new SignatureWriter();
+ SignatureVisitor signatureRemapper = createSignatureRemapper(signatureWriter);
+ if (typeSignature) {
+ signatureReader.acceptType(signatureRemapper);
+ } else {
+ signatureReader.accept(signatureRemapper);
+ }
+ return signatureWriter.toString();
+ }
+
+ /**
+ * Constructs a new remapper for signatures. The default implementation of this method returns a
+ * new {@link SignatureRemapper}.
+ *
+ * @param signatureVisitor the SignatureVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ * @deprecated use {@link #createSignatureRemapper} instead.
+ */
+ @Deprecated
+ protected SignatureVisitor createRemappingSignatureAdapter(
+ final SignatureVisitor signatureVisitor) {
+ return createSignatureRemapper(signatureVisitor);
+ }
+
+ /**
+ * Constructs a new remapper for signatures. The default implementation of this method returns a
+ * new {@link SignatureRemapper}.
+ *
+ * @param signatureVisitor the SignatureVisitor the remapper must delegate to.
+ * @return the newly created remapper.
+ */
+ protected SignatureVisitor createSignatureRemapper(final SignatureVisitor signatureVisitor) {
+ return new SignatureRemapper(signatureVisitor, this);
+ }
+
+ /**
+ * Maps an annotation attribute name. The default implementation of this method returns the given
+ * name, unchanged. Subclasses can override.
+ *
+ * @param descriptor the descriptor of the annotation class.
+ * @param name the name of the annotation attribute.
+ * @return the new name of the annotation attribute.
+ */
+ public String mapAnnotationAttributeName(final String descriptor, final String name) {
+ return name;
+ }
+
+ /**
+ * Maps an inner class name to its new name. The default implementation of this method provides a
+ * strategy that will work for inner classes produced by Java, but not necessarily other
+ * languages. Subclasses can override.
+ *
+ * @param name the fully-qualified internal name of the inner class (see {@link
+ * Type#getInternalName()}).
+ * @param ownerName the internal name of the owner class of the inner class (see {@link
+ * Type#getInternalName()}).
+ * @param innerName the internal name of the inner class (see {@link Type#getInternalName()}).
+ * @return the new inner name of the inner class.
+ */
+ public String mapInnerClassName(
+ final String name, final String ownerName, final String innerName) {
+ final String remappedInnerName = this.mapType(name);
+
+ if (remappedInnerName.equals(name)) {
+ return innerName;
+ } else {
+ int originSplit = name.lastIndexOf('/');
+ int remappedSplit = remappedInnerName.lastIndexOf('/');
+ if (originSplit != -1 && remappedSplit != -1) {
+ if (name.substring(originSplit).equals(remappedInnerName.substring(remappedSplit))) {
+ // class name not changed
+ return innerName;
+ }
+ }
+ }
+
+ if (remappedInnerName.contains("$")) {
+ int index = remappedInnerName.lastIndexOf('$') + 1;
+ while (index < remappedInnerName.length()
+ && Character.isDigit(remappedInnerName.charAt(index))) {
+ index++;
+ }
+ return remappedInnerName.substring(index);
+ } else {
+ return innerName;
+ }
+ }
+
+ /**
+ * Maps a method name to its new name. The default implementation of this method returns the given
+ * name, unchanged. Subclasses can override.
+ *
+ * @param owner the internal name of the owner class of the method (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the method.
+ * @param descriptor the descriptor of the method.
+ * @return the new name of the method.
+ */
+ public String mapMethodName(final String owner, final String name, final String descriptor) {
+ return name;
+ }
+
+ /**
+ * Maps an invokedynamic or a constant dynamic method name to its new name. The default
+ * implementation of this method returns the given name, unchanged. Subclasses can override.
+ *
+ * @param name the name of the method.
+ * @param descriptor the descriptor of the method.
+ * @return the new name of the method.
+ */
+ public String mapInvokeDynamicMethodName(final String name, final String descriptor) {
+ return name;
+ }
+
+ /**
+ * Maps a record component name to its new name. The default implementation of this method returns
+ * the given name, unchanged. Subclasses can override.
+ *
+ * @param owner the internal name of the owner class of the field (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the field.
+ * @param descriptor the descriptor of the field.
+ * @return the new name of the field.
+ */
+ public String mapRecordComponentName(
+ final String owner, final String name, final String descriptor) {
+ return name;
+ }
+
+ /**
+ * Maps a field name to its new name. The default implementation of this method returns the given
+ * name, unchanged. Subclasses can override.
+ *
+ * @param owner the internal name of the owner class of the field (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the field.
+ * @param descriptor the descriptor of the field.
+ * @return the new name of the field.
+ */
+ public String mapFieldName(final String owner, final String name, final String descriptor) {
+ return name;
+ }
+
+ /**
+ * Maps a package name to its new name. The default implementation of this method returns the
+ * given name, unchanged. Subclasses can override.
+ *
+ * @param name the fully qualified name of the package (using dots).
+ * @return the new name of the package.
+ */
+ public String mapPackageName(final String name) {
+ return name;
+ }
+
+ /**
+ * Maps a module name to its new name. The default implementation of this method returns the given
+ * name, unchanged. Subclasses can override.
+ *
+ * @param name the fully qualified name (using dots) of a module.
+ * @return the new name of the module.
+ */
+ public String mapModuleName(final String name) {
+ return name;
+ }
+
+ /**
+ * Maps the internal name of a class to its new name. The default implementation of this method
+ * returns the given name, unchanged. Subclasses can override.
+ *
+ * @param internalName the internal name of a class (see {@link Type#getInternalName()}).
+ * @return the new internal name (see {@link Type#getInternalName()}).
+ */
+ public String map(final String internalName) {
+ return internalName;
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java
new file mode 100644
index 00000000..7daaaec2
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java
@@ -0,0 +1,492 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ClassVisitor} that adds a serial version unique identifier to a class if missing. A
+ * typical usage of this class is:
+ *
+ * <pre>
+ * ClassWriter classWriter = new ClassWriter(...);
+ * ClassVisitor svuidAdder = new SerialVersionUIDAdder(classWriter);
+ * ClassVisitor classVisitor = new MyClassAdapter(svuidAdder);
+ * new ClassReader(orginalClass).accept(classVisitor, 0);
+ * </pre>
+ *
+ * <p>The SVUID algorithm can be found at <a href=
+ * "https://docs.oracle.com/javase/10/docs/specs/serialization/class.html#stream-unique-identifiers"
+ * >https://docs.oracle.com/javase/10/docs/specs/serialization/class.html#stream-unique-identifiers</a>:
+ *
+ * <p>The serialVersionUID is computed using the signature of a stream of bytes that reflect the
+ * class definition. The National Institute of Standards and Technology (NIST) Secure Hash Algorithm
+ * (SHA-1) is used to compute a signature for the stream. The first two 32-bit quantities are used
+ * to form a 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data types to a
+ * sequence of bytes. The values input to the stream are defined by the Java Virtual Machine (VM)
+ * specification for classes.
+ *
+ * <p>The sequence of items in the stream is as follows:
+ *
+ * <ol>
+ * <li>The class name written using UTF encoding.
+ * <li>The class modifiers written as a 32-bit integer.
+ * <li>The name of each interface sorted by name written using UTF encoding.
+ * <li>For each field of the class sorted by field name (except private static and private
+ * transient fields):
+ * <ol>
+ * <li>The name of the field in UTF encoding.
+ * <li>The modifiers of the field written as a 32-bit integer.
+ * <li>The descriptor of the field in UTF encoding
+ * </ol>
+ * <li>If a class initializer exists, write out the following:
+ * <ol>
+ * <li>The name of the method, &lt;clinit&gt;, in UTF encoding.
+ * <li>The modifier of the method, STATIC, written as a 32-bit integer.
+ * <li>The descriptor of the method, ()V, in UTF encoding.
+ * </ol>
+ * <li>For each non-private constructor sorted by method name and signature:
+ * <ol>
+ * <li>The name of the method, &lt;init&gt;, in UTF encoding.
+ * <li>The modifiers of the method written as a 32-bit integer.
+ * <li>The descriptor of the method in UTF encoding.
+ * </ol>
+ * <li>For each non-private method sorted by method name and signature:
+ * <ol>
+ * <li>The name of the method in UTF encoding.
+ * <li>The modifiers of the method written as a 32-bit integer.
+ * <li>The descriptor of the method in UTF encoding.
+ * </ol>
+ * <li>The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and
+ * produces five 32-bit values sha[0..4].
+ * <li>The hash value is assembled from the first and second 32-bit values of the SHA-1 message
+ * digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an
+ * array of five int values named sha, the hash value would be computed as follows: long hash
+ * = ((sha[0] &gt;&gt;&gt; 24) &amp; 0xFF) | ((sha[0] &gt;&gt;&gt; 16) &amp; 0xFF) &lt;&lt; 8
+ * | ((sha[0] &gt;&gt;&gt; 8) &amp; 0xFF) &lt;&lt; 16 | ((sha[0] &gt;&gt;&gt; 0) &amp; 0xFF)
+ * &lt;&lt; 24 | ((sha[1] &gt;&gt;&gt; 24) &amp; 0xFF) &lt;&lt; 32 | ((sha[1] &gt;&gt;&gt; 16)
+ * &amp; 0xFF) &lt;&lt; 40 | ((sha[1] &gt;&gt;&gt; 8) &amp; 0xFF) &lt;&lt; 48 | ((sha[1]
+ * &gt;&gt;&gt; 0) &amp; 0xFF) &lt;&lt; 56;
+ * </ol>
+ *
+ * @author Rajendra Inamdar, Vishal Vishnoi
+ */
+// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+public class SerialVersionUIDAdder extends ClassVisitor {
+
+ /** The JVM name of static initializer methods. */
+ private static final String CLINIT = "<clinit>";
+
+ /** A flag that indicates if we need to compute SVUID. */
+ private boolean computeSvuid;
+
+ /** Whether the class already has a SVUID. */
+ private boolean hasSvuid;
+
+ /** The class access flags. */
+ private int access;
+
+ /** The internal name of the class. */
+ private String name;
+
+ /** The interfaces implemented by the class. */
+ private String[] interfaces;
+
+ /** The fields of the class that are needed to compute the SVUID. */
+ private Collection<Item> svuidFields;
+
+ /** Whether the class has a static initializer. */
+ private boolean hasStaticInitializer;
+
+ /** The constructors of the class that are needed to compute the SVUID. */
+ private Collection<Item> svuidConstructors;
+
+ /** The methods of the class that are needed to compute the SVUID. */
+ private Collection<Item> svuidMethods;
+
+ /**
+ * Constructs a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link #SerialVersionUIDAdder(int, ClassVisitor)}
+ * version.
+ *
+ * @param classVisitor a {@link ClassVisitor} to which this visitor will delegate calls.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public SerialVersionUIDAdder(final ClassVisitor classVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, classVisitor);
+ if (getClass() != SerialVersionUIDAdder.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link SerialVersionUIDAdder}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param classVisitor a {@link ClassVisitor} to which this visitor will delegate calls.
+ */
+ protected SerialVersionUIDAdder(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Overridden methods
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ // Get the class name, access flags, and interfaces information (step 1, 2 and 3) for SVUID
+ // computation.
+ computeSvuid = (access & Opcodes.ACC_ENUM) == 0;
+
+ if (computeSvuid) {
+ this.name = name;
+ this.access = access;
+ this.interfaces = interfaces.clone();
+ this.svuidFields = new ArrayList<>();
+ this.svuidConstructors = new ArrayList<>();
+ this.svuidMethods = new ArrayList<>();
+ }
+
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ // Get constructor and method information (step 5 and 7). Also determine if there is a class
+ // initializer (step 6).
+ if (computeSvuid) {
+ if (CLINIT.equals(name)) {
+ hasStaticInitializer = true;
+ }
+ // Collect the non private constructors and methods. Only the ACC_PUBLIC, ACC_PRIVATE,
+ // ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and
+ // ACC_STRICT flags are used.
+ int mods =
+ access
+ & (Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_PRIVATE
+ | Opcodes.ACC_PROTECTED
+ | Opcodes.ACC_STATIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_SYNCHRONIZED
+ | Opcodes.ACC_NATIVE
+ | Opcodes.ACC_ABSTRACT
+ | Opcodes.ACC_STRICT);
+
+ if ((access & Opcodes.ACC_PRIVATE) == 0) {
+ if ("<init>".equals(name)) {
+ svuidConstructors.add(new Item(name, mods, descriptor));
+ } else if (!CLINIT.equals(name)) {
+ svuidMethods.add(new Item(name, mods, descriptor));
+ }
+ }
+ }
+
+ return super.visitMethod(access, name, descriptor, signature, exceptions);
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value) {
+ // Get the class field information for step 4 of the algorithm. Also determine if the class
+ // already has a SVUID.
+ if (computeSvuid) {
+ if ("serialVersionUID".equals(name)) {
+ // Since the class already has SVUID, we won't be computing it.
+ computeSvuid = false;
+ hasSvuid = true;
+ }
+ // Collect the non private fields. Only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED,
+ // ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when computing
+ // serialVersionUID values.
+ if ((access & Opcodes.ACC_PRIVATE) == 0
+ || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
+ int mods =
+ access
+ & (Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_PRIVATE
+ | Opcodes.ACC_PROTECTED
+ | Opcodes.ACC_STATIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_VOLATILE
+ | Opcodes.ACC_TRANSIENT);
+ svuidFields.add(new Item(name, mods, desc));
+ }
+ }
+
+ return super.visitField(access, name, desc, signature, value);
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String innerClassName,
+ final String outerName,
+ final String innerName,
+ final int innerClassAccess) {
+ // Handles a bizarre special case. Nested classes (static classes declared inside another class)
+ // that are protected have their access bit set to public in their class files to deal with some
+ // odd reflection situation. Our SVUID computation must do as the JVM does and ignore access
+ // bits in the class file in favor of the access bits of the InnerClass attribute.
+ if ((name != null) && name.equals(innerClassName)) {
+ this.access = innerClassAccess;
+ }
+ super.visitInnerClass(innerClassName, outerName, innerName, innerClassAccess);
+ }
+
+ @Override
+ public void visitEnd() {
+ // Add the SVUID field to the class if it doesn't have one.
+ if (computeSvuid && !hasSvuid) {
+ try {
+ addSVUID(computeSVUID());
+ } catch (IOException e) {
+ throw new IllegalStateException("Error while computing SVUID for " + name, e);
+ }
+ }
+
+ super.visitEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns true if the class already has a SVUID field. The result of this method is only valid
+ * when visitEnd has been called.
+ *
+ * @return true if the class already has a SVUID field.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ public boolean hasSVUID() {
+ return hasSvuid;
+ }
+
+ /**
+ * Adds a final static serialVersionUID field to the class, with the given value.
+ *
+ * @param svuid the serialVersionUID field value.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ protected void addSVUID(final long svuid) {
+ FieldVisitor fieldVisitor =
+ super.visitField(
+ Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
+ if (fieldVisitor != null) {
+ fieldVisitor.visitEnd();
+ }
+ }
+
+ /**
+ * Computes and returns the value of SVUID.
+ *
+ * @return the serial version UID.
+ * @throws IOException if an I/O error occurs.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ protected long computeSVUID() throws IOException {
+ long svuid = 0;
+
+ try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
+
+ // 1. The class name written using UTF encoding.
+ dataOutputStream.writeUTF(name.replace('/', '.'));
+
+ // 2. The class modifiers written as a 32-bit integer.
+ int mods = access;
+ if ((mods & Opcodes.ACC_INTERFACE) != 0) {
+ mods =
+ svuidMethods.isEmpty() ? (mods & ~Opcodes.ACC_ABSTRACT) : (mods | Opcodes.ACC_ABSTRACT);
+ }
+ dataOutputStream.writeInt(
+ mods
+ & (Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_INTERFACE
+ | Opcodes.ACC_ABSTRACT));
+
+ // 3. The name of each interface sorted by name written using UTF encoding.
+ Arrays.sort(interfaces);
+ for (String interfaceName : interfaces) {
+ dataOutputStream.writeUTF(interfaceName.replace('/', '.'));
+ }
+
+ // 4. For each field of the class sorted by field name (except private static and private
+ // transient fields):
+ // 1. The name of the field in UTF encoding.
+ // 2. The modifiers of the field written as a 32-bit integer.
+ // 3. The descriptor of the field in UTF encoding.
+ // Note that field signatures are not dot separated. Method and constructor signatures are dot
+ // separated. Go figure...
+ writeItems(svuidFields, dataOutputStream, false);
+
+ // 5. If a class initializer exists, write out the following:
+ // 1. The name of the method, <clinit>, in UTF encoding.
+ // 2. The modifier of the method, ACC_STATIC, written as a 32-bit integer.
+ // 3. The descriptor of the method, ()V, in UTF encoding.
+ if (hasStaticInitializer) {
+ dataOutputStream.writeUTF(CLINIT);
+ dataOutputStream.writeInt(Opcodes.ACC_STATIC);
+ dataOutputStream.writeUTF("()V");
+ }
+
+ // 6. For each non-private constructor sorted by method name and signature:
+ // 1. The name of the method, <init>, in UTF encoding.
+ // 2. The modifiers of the method written as a 32-bit integer.
+ // 3. The descriptor of the method in UTF encoding.
+ writeItems(svuidConstructors, dataOutputStream, true);
+
+ // 7. For each non-private method sorted by method name and signature:
+ // 1. The name of the method in UTF encoding.
+ // 2. The modifiers of the method written as a 32-bit integer.
+ // 3. The descriptor of the method in UTF encoding.
+ writeItems(svuidMethods, dataOutputStream, true);
+
+ dataOutputStream.flush();
+
+ // 8. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and
+ // produces five 32-bit values sha[0..4].
+ byte[] hashBytes = computeSHAdigest(byteArrayOutputStream.toByteArray());
+
+ // 9. The hash value is assembled from the first and second 32-bit values of the SHA-1 message
+ // digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an
+ // array of five int values named sha, the hash value would be computed as follows:
+ for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
+ svuid = (svuid << 8) | (hashBytes[i] & 0xFF);
+ }
+ }
+
+ return svuid;
+ }
+
+ /**
+ * Returns the SHA-1 message digest of the given value.
+ *
+ * @param value the value whose SHA message digest must be computed.
+ * @return the SHA-1 message digest of the given value.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ protected byte[] computeSHAdigest(final byte[] value) {
+ try {
+ return MessageDigest.getInstance("SHA").digest(value);
+ } catch (NoSuchAlgorithmException e) {
+ throw new UnsupportedOperationException(e);
+ }
+ }
+
+ /**
+ * Sorts the items in the collection and writes it to the given output stream.
+ *
+ * @param itemCollection a collection of items.
+ * @param dataOutputStream where the items must be written.
+ * @param dotted whether package names must use dots, instead of slashes.
+ * @exception IOException if an error occurs.
+ */
+ private static void writeItems(
+ final Collection<Item> itemCollection,
+ final DataOutput dataOutputStream,
+ final boolean dotted)
+ throws IOException {
+ Item[] items = itemCollection.toArray(new Item[0]);
+ Arrays.sort(items);
+ for (Item item : items) {
+ dataOutputStream.writeUTF(item.name);
+ dataOutputStream.writeInt(item.access);
+ dataOutputStream.writeUTF(dotted ? item.descriptor.replace('/', '.') : item.descriptor);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Inner classes
+ // -----------------------------------------------------------------------------------------------
+
+ private static final class Item implements Comparable<Item> {
+
+ final String name;
+ final int access;
+ final String descriptor;
+
+ Item(final String name, final int access, final String descriptor) {
+ this.name = name;
+ this.access = access;
+ this.descriptor = descriptor;
+ }
+
+ @Override
+ public int compareTo(final Item item) {
+ int result = name.compareTo(item.name);
+ if (result == 0) {
+ result = descriptor.compareTo(item.descriptor);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (other instanceof Item) {
+ return compareTo((Item) other) == 0;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode() ^ descriptor.hashCode();
+ }
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java
new file mode 100644
index 00000000..66c30c96
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java
@@ -0,0 +1,173 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+/**
+ * A {@link SignatureVisitor} that remaps types with a {@link Remapper}.
+ *
+ * @author Eugene Kuleshov
+ */
+public class SignatureRemapper extends SignatureVisitor {
+
+ private final SignatureVisitor signatureVisitor;
+
+ private final Remapper remapper;
+
+ private ArrayList<String> classNames = new ArrayList<>();
+
+ /**
+ * Constructs a new {@link SignatureRemapper}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #SignatureRemapper(int,SignatureVisitor,Remapper)} version.
+ *
+ * @param signatureVisitor the signature visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited signature.
+ */
+ public SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper) {
+ this(/* latest api = */ Opcodes.ASM9, signatureVisitor, remapper);
+ }
+
+ /**
+ * Constructs a new {@link SignatureRemapper}.
+ *
+ * @param api the ASM API version supported by this remapper. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param signatureVisitor the signature visitor this remapper must delegate to.
+ * @param remapper the remapper to use to remap the types in the visited signature.
+ */
+ protected SignatureRemapper(
+ final int api, final SignatureVisitor signatureVisitor, final Remapper remapper) {
+ super(api);
+ this.signatureVisitor = signatureVisitor;
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visitClassType(final String name) {
+ classNames.add(name);
+ signatureVisitor.visitClassType(remapper.mapType(name));
+ }
+
+ @Override
+ public void visitInnerClassType(final String name) {
+ String outerClassName = classNames.remove(classNames.size() - 1);
+ String className = outerClassName + '$' + name;
+ classNames.add(className);
+ String remappedOuter = remapper.mapType(outerClassName) + '$';
+ String remappedName = remapper.mapType(className);
+ int index =
+ remappedName.startsWith(remappedOuter)
+ ? remappedOuter.length()
+ : remappedName.lastIndexOf('$') + 1;
+ signatureVisitor.visitInnerClassType(remappedName.substring(index));
+ }
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ signatureVisitor.visitFormalTypeParameter(name);
+ }
+
+ @Override
+ public void visitTypeVariable(final String name) {
+ signatureVisitor.visitTypeVariable(name);
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ signatureVisitor.visitArrayType();
+ return this;
+ }
+
+ @Override
+ public void visitBaseType(final char descriptor) {
+ signatureVisitor.visitBaseType(descriptor);
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ signatureVisitor.visitClassBound();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ signatureVisitor.visitExceptionType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ signatureVisitor.visitInterface();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ signatureVisitor.visitInterfaceBound();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ signatureVisitor.visitParameterType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ signatureVisitor.visitReturnType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ signatureVisitor.visitSuperclass();
+ return this;
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ signatureVisitor.visitTypeArgument();
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(final char wildcard) {
+ signatureVisitor.visitTypeArgument(wildcard);
+ return this;
+ }
+
+ @Override
+ public void visitEnd() {
+ signatureVisitor.visitEnd();
+ classNames.remove(classNames.size() - 1);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java
new file mode 100644
index 00000000..6803d948
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SimpleRemapper.java
@@ -0,0 +1,104 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * A {@link Remapper} using a {@link Map} to define its mapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class SimpleRemapper extends Remapper {
+
+ private final Map<String, String> mapping;
+
+ /**
+ * Constructs a new {@link SimpleRemapper} with the given mapping.
+ *
+ * @param mapping a map specifying a remapping as follows:
+ * <ul>
+ * <li>for method names, the key is the owner, name and descriptor of the method (in the
+ * form &lt;owner&gt;.&lt;name&gt;&lt;descriptor&gt;), and the value is the new method
+ * name.
+ * <li>for invokedynamic method names, the key is the name and descriptor of the method (in
+ * the form .&lt;name&gt;&lt;descriptor&gt;), and the value is the new method name.
+ * <li>for field and attribute names, the key is the owner and name of the field or
+ * attribute (in the form &lt;owner&gt;.&lt;name&gt;), and the value is the new field
+ * name.
+ * <li>for internal names, the key is the old internal name, and the value is the new
+ * internal name (see {@link org.objectweb.asm.Type#getInternalName()}).
+ * </ul>
+ */
+ public SimpleRemapper(final Map<String, String> mapping) {
+ this.mapping = mapping;
+ }
+
+ /**
+ * Constructs a new {@link SimpleRemapper} with the given mapping.
+ *
+ * @param oldName the key corresponding to a method, field or internal name (see {@link
+ * #SimpleRemapper(Map)} for the format of these keys).
+ * @param newName the new method, field or internal name (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ */
+ public SimpleRemapper(final String oldName, final String newName) {
+ this.mapping = Collections.singletonMap(oldName, newName);
+ }
+
+ @Override
+ public String mapMethodName(final String owner, final String name, final String descriptor) {
+ String remappedName = map(owner + '.' + name + descriptor);
+ return remappedName == null ? name : remappedName;
+ }
+
+ @Override
+ public String mapInvokeDynamicMethodName(final String name, final String descriptor) {
+ String remappedName = map('.' + name + descriptor);
+ return remappedName == null ? name : remappedName;
+ }
+
+ @Override
+ public String mapAnnotationAttributeName(final String descriptor, final String name) {
+ String remappedName = map(descriptor + '.' + name);
+ return remappedName == null ? name : remappedName;
+ }
+
+ @Override
+ public String mapFieldName(final String owner, final String name, final String descriptor) {
+ String remappedName = map(owner + '.' + name);
+ return remappedName == null ? name : remappedName;
+ }
+
+ @Override
+ public String map(final String key) {
+ return mapping.get(key);
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java
new file mode 100644
index 00000000..9c1144c3
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java
@@ -0,0 +1,124 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ClassVisitor} that merges &lt;clinit&gt; methods into a single one. All the existing
+ * &lt;clinit&gt; methods are renamed, and a new one is created, which calls all the renamed
+ * methods.
+ *
+ * @author Eric Bruneton
+ */
+public class StaticInitMerger extends ClassVisitor {
+
+ /** The internal name of the visited class. */
+ private String owner;
+
+ /** The prefix to use to rename the existing &lt;clinit&gt; methods. */
+ private final String renamedClinitMethodPrefix;
+
+ /** The number of &lt;clinit&gt; methods visited so far. */
+ private int numClinitMethods;
+
+ /** The MethodVisitor for the merged &lt;clinit&gt; method. */
+ private MethodVisitor mergedClinitVisitor;
+
+ /**
+ * Constructs a new {@link StaticInitMerger}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #StaticInitMerger(int, String, ClassVisitor)} version.
+ *
+ * @param prefix the prefix to use to rename the existing &lt;clinit&gt; methods.
+ * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ public StaticInitMerger(final String prefix, final ClassVisitor classVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, prefix, classVisitor);
+ }
+
+ /**
+ * Constructs a new {@link StaticInitMerger}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param prefix the prefix to use to rename the existing &lt;clinit&gt; methods.
+ * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ protected StaticInitMerger(final int api, final String prefix, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ this.renamedClinitMethodPrefix = prefix;
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ super.visit(version, access, name, signature, superName, interfaces);
+ this.owner = name;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor;
+ if ("<clinit>".equals(name)) {
+ int newAccess = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
+ String newName = renamedClinitMethodPrefix + numClinitMethods++;
+ methodVisitor = super.visitMethod(newAccess, newName, descriptor, signature, exceptions);
+
+ if (mergedClinitVisitor == null) {
+ mergedClinitVisitor = super.visitMethod(newAccess, name, descriptor, null, null);
+ }
+ mergedClinitVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newName, descriptor, false);
+ } else {
+ methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
+ }
+ return methodVisitor;
+ }
+
+ @Override
+ public void visitEnd() {
+ if (mergedClinitVisitor != null) {
+ mergedClinitVisitor.visitInsn(Opcodes.RETURN);
+ mergedClinitVisitor.visitMaxs(0, 0);
+ }
+ super.visitEnd();
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/TableSwitchGenerator.java b/asm-commons/src/main/java/org/objectweb/asm/commons/TableSwitchGenerator.java
new file mode 100644
index 00000000..0cfadd91
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/TableSwitchGenerator.java
@@ -0,0 +1,51 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Label;
+
+/**
+ * A code generator for switch statements.
+ *
+ * @author Juozas Baliuka
+ * @author Chris Nokleberg
+ * @author Eric Bruneton
+ */
+public interface TableSwitchGenerator {
+
+ /**
+ * Generates the code for a switch case.
+ *
+ * @param key the switch case key.
+ * @param end a label that corresponds to the end of the switch statement.
+ */
+ void generateCase(int key, Label end);
+
+ /** Generates the code for the default switch case. */
+ void generateDefault();
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java
new file mode 100644
index 00000000..b6dffeed
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java
@@ -0,0 +1,126 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.commons;
+
+import java.util.Collections;
+import java.util.Comparator;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+
+/**
+ * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers are sorted in a
+ * method innermost-to-outermost. This allows the programmer to add handlers without worrying about
+ * ordering them correctly with respect to existing, in-code handlers.
+ *
+ * <p>Behavior is only defined for properly-nested handlers. If any "try" blocks overlap (something
+ * that isn't possible in Java code) then this may not do what you want. In fact, this adapter just
+ * sorts by the length of the "try" block, taking advantage of the fact that a given try block must
+ * be larger than any block it contains).
+ *
+ * @author Adrian Sampson
+ */
+public class TryCatchBlockSorter extends MethodNode {
+
+ /**
+ * Constructs a new {@link TryCatchBlockSorter}.
+ *
+ * @param methodVisitor the method visitor to which this visitor must delegate method calls. May
+ * be {@literal null}.
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the method's signature. May be {@literal null} if the method parameters,
+ * return type and exceptions do not use generic types.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public TryCatchBlockSorter(
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ this(
+ /* latest api = */ Opcodes.ASM9,
+ methodVisitor,
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions);
+ if (getClass() != TryCatchBlockSorter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ protected TryCatchBlockSorter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ super(api, access, name, descriptor, signature, exceptions);
+ this.mv = methodVisitor;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Sort the TryCatchBlockNode elements by the length of their "try" block.
+ Collections.sort(
+ tryCatchBlocks,
+ new Comparator<TryCatchBlockNode>() {
+
+ @Override
+ public int compare(
+ final TryCatchBlockNode tryCatchBlockNode1,
+ final TryCatchBlockNode tryCatchBlockNode2) {
+ return blockLength(tryCatchBlockNode1) - blockLength(tryCatchBlockNode2);
+ }
+
+ private int blockLength(final TryCatchBlockNode tryCatchBlockNode) {
+ int startIndex = instructions.indexOf(tryCatchBlockNode.start);
+ int endIndex = instructions.indexOf(tryCatchBlockNode.end);
+ return endIndex - startIndex;
+ }
+ });
+ // Update the 'target' of each try catch block annotation.
+ for (int i = 0; i < tryCatchBlocks.size(); ++i) {
+ tryCatchBlocks.get(i).updateIndex(i);
+ }
+ if (mv != null) {
+ accept(mv);
+ }
+ }
+}
diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/package.html b/asm-commons/src/main/java/org/objectweb/asm/commons/package.html
new file mode 100644
index 00000000..f24ae4fa
--- /dev/null
+++ b/asm-commons/src/main/java/org/objectweb/asm/commons/package.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm.commons</title>
+</head>
+<body>
+Provides some useful class and method adapters. <em>The preferred way of using
+these adapters is by chaining them together and to custom adapters (instead of
+inheriting from them)</em>. Indeed this approach provides more combination
+possibilities than inheritance. For instance, suppose you want to implement an
+adapter MyAdapter than needs sorted local variables and intermediate stack map
+frame values taking into account the local variables sort. By using inheritance,
+this would require MyAdapter to extend AnalyzerAdapter, itself extending
+LocalVariablesSorter. But AnalyzerAdapter is not a subclass of
+LocalVariablesSorter, so this is not possible. On the contrary, by using
+delegation, you can make LocalVariablesSorter delegate to AnalyzerAdapter,
+itself delegating to MyAdapter. In this case AnalyzerAdapter computes
+intermediate frames based on the output of LocalVariablesSorter, and MyAdapter
+can add new locals by calling the newLocal method on LocalVariablesSorter, and
+can get the stack map frame state before each instruction by reading the locals
+and stack fields in AnalyzerAdapter (this requires references from MyAdapter
+back to LocalVariablesSorter and AnalyzerAdapter).
+</body>
diff --git a/asm-commons/src/resources/java/SerialVersionAnonymousInnerClass.java b/asm-commons/src/resources/java/SerialVersionAnonymousInnerClass.java
new file mode 100644
index 00000000..29b3aac6
--- /dev/null
+++ b/asm-commons/src/resources/java/SerialVersionAnonymousInnerClass.java
@@ -0,0 +1,45 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+import java.io.Serializable;
+
+/**
+ * Test case for SerialVersionUIDAdder.
+ *
+ * @author Eric Bruneton
+ */
+class SerialVersionAnonymousInnerClass implements Serializable {
+
+ // No serial version UID on purpose, to test SerialVersionUIDAdder.
+
+ public static final SerialVersionAnonymousInnerClass anonymousInnerClass =
+ new SerialVersionAnonymousInnerClass() {};
+
+ SerialVersionAnonymousInnerClass() {}
+
+ public void someMethod() {}
+}
diff --git a/asm-commons/src/resources/java/SerialVersionClass.java b/asm-commons/src/resources/java/SerialVersionClass.java
new file mode 100644
index 00000000..f0490946
--- /dev/null
+++ b/asm-commons/src/resources/java/SerialVersionClass.java
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+import java.io.Serializable;
+
+/**
+ * Test case for SerialVersionUIDAdder.
+ *
+ * @author Eric Bruneton
+ */
+class SerialVersionClass implements Serializable {
+
+ // No serial version UID on purpose, to test SerialVersionUIDAdder.
+
+ protected static final int someField = 32;
+
+ static {
+ assert someField > 0;
+ }
+
+ SerialVersionClass() {}
+
+ public Object[] someMethod() {
+ return new Object[0];
+ }
+}
diff --git a/asm-commons/src/resources/java/SerialVersionEmptyInterface.java b/asm-commons/src/resources/java/SerialVersionEmptyInterface.java
new file mode 100644
index 00000000..19c7cfff
--- /dev/null
+++ b/asm-commons/src/resources/java/SerialVersionEmptyInterface.java
@@ -0,0 +1,35 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+import java.io.Serializable;
+
+/**
+ * Test case for SerialVersionUIDAdder.
+ *
+ * @author Eric Bruneton
+ */
+interface SerialVersionEmptyInterface extends Serializable {}
diff --git a/asm-commons/src/resources/java/SerialVersionEnum.java b/asm-commons/src/resources/java/SerialVersionEnum.java
new file mode 100644
index 00000000..3edc6220
--- /dev/null
+++ b/asm-commons/src/resources/java/SerialVersionEnum.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+/**
+ * Test case for SerialVersionUIDAdder.
+ *
+ * @author Eric Bruneton
+ */
+enum SerialVersionEnum {
+ V1,
+ V2,
+ V3
+}
diff --git a/asm-commons/src/resources/java/SerialVersionInterface.java b/asm-commons/src/resources/java/SerialVersionInterface.java
new file mode 100644
index 00000000..0698594e
--- /dev/null
+++ b/asm-commons/src/resources/java/SerialVersionInterface.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+import java.io.Serializable;
+
+/**
+ * Test case for SerialVersionUIDAdder.
+ *
+ * @author Eric Bruneton
+ */
+interface SerialVersionInterface extends Serializable {
+ void someMethod(Object[] args);
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java
new file mode 100644
index 00000000..0b676c08
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java
@@ -0,0 +1,843 @@
+// ASM: a very smAall and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.objectweb.asm.commons.MethodNodeBuilder.buildClassWithMethod;
+import static org.objectweb.asm.commons.MethodNodeBuilder.toText;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link AdviceAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class AdviceAdapterTest extends AsmTest {
+
+ @Test
+ void testAllMethods_invalidConstructor() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 2, 2).insn(Opcodes.IRETURN).build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ Executable accept = () -> inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, accept);
+ assertEquals("Invalid return in constructor", exception.getMessage());
+ }
+
+ @Test
+ void testAllMethods_simpleConstructor() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 2, 2)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #2.
+ // After instrumentation, expect an after advice here, before instruction #2.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(2).withAfterAdviceAt(2).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithTwoSuperInitInTwoBranches() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 2)
+ .iload(1)
+ .insn(Opcodes.ICONST_1)
+ .insn(Opcodes.ICONST_2)
+ .insn(Opcodes.IADD)
+ .jumpInsn(Opcodes.IF_ICMPEQ, label0)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #7.
+ .go(label1)
+ .label(label0)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #11.
+ .label(label1)
+ .typeInsn(Opcodes.NEW, "java/lang/RuntimeException")
+ .insn(Opcodes.DUP)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false)
+ // After instrumentation, expect an after advice here, before instruction #15.
+ .athrow()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(7, 11)
+ .withAfterAdviceAt(15)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"true", "false"})
+ void testAllMethods_constructorWithTwoSuperInitInTwoSwitchBranches(final boolean useTableSwitch) {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 4, 2)
+ .iload(1)
+ .insn(Opcodes.ICONST_1)
+ .insn(Opcodes.ICONST_2)
+ .insn(Opcodes.IADD)
+ .switchto(label0, label1, useTableSwitch)
+ .label(label0)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #8.
+ .go(label2)
+ .label(label1)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #12.
+ .go(label2)
+ .label(label2)
+ .typeInsn(Opcodes.NEW, "java/lang/RuntimeException")
+ .insn(Opcodes.DUP)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false)
+ // After instrumentation, expect an after advice here, before instruction #17.
+ .athrow()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(8, 12)
+ .withAfterAdviceAt(17)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithSuperInitsInNormalAndHandlerBranches() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 2, 2)
+ .trycatch(label0, label1, label2)
+ .label(label0)
+ .insn(Opcodes.NOP)
+ .label(label1)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #5.
+ .go(label3)
+ .label(label2)
+ .insn(Opcodes.POP)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #10.
+ .label(label3)
+ // After instrumentation, expect an after advice here, before instruction #11.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(5, 10)
+ .withAfterAdviceAt(11)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithUninitThisInTwoBranches() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 6, 2)
+ .iload(1)
+ .insn(Opcodes.I2L)
+ .insn(Opcodes.LCONST_0)
+ .insn(Opcodes.LCONST_1)
+ .insn(Opcodes.LADD)
+ .insn(Opcodes.LCMP)
+ .ifne(label0)
+ .insn(Opcodes.NOP)
+ .typeInsn(Opcodes.NEW, "C")
+ .insn(Opcodes.DUP)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .astore(1)
+ .aload(0)
+ .go(label1)
+ .label(label0)
+ .iconst_0()
+ .aload(0)
+ .insn(Opcodes.SWAP)
+ .insn(Opcodes.POP)
+ .label(label1)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #21.
+ // After instrumentation, expect an after advice here, before instruction #21.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(21).withAfterAdviceAt(21).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithDupX1() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 2)
+ .typeInsn(Opcodes.NEW, "C")
+ .astore(1)
+ .aload(1)
+ .aload(0)
+ .insn(Opcodes.DUP_X1)
+ .insn(Opcodes.POP)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #8.
+ // After instrumentation, expect an after advice here, before instruction #8.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(8).withAfterAdviceAt(8).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithDupX2() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 4, 2)
+ .typeInsn(Opcodes.NEW, "C")
+ .astore(1)
+ .aload(1)
+ .aconst_null()
+ .aload(0)
+ .insn(Opcodes.DUP_X2)
+ .insn(Opcodes.POP2)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // No method enter here because the above call does not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #9.
+ // After instrumentation, expect an after advice here, before instruction #9.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(9).withAfterAdviceAt(9).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithDup2() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 4, 2)
+ .typeInsn(Opcodes.NEW, "C")
+ .astore(1)
+ .aload(0)
+ .aload(1)
+ .insn(Opcodes.DUP2)
+ .insn(Opcodes.POP2)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #8.
+ // After instrumentation, expect an after advice here, before instruction #8.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(8).withAfterAdviceAt(8).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithDup2X1() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 5, 2)
+ .typeInsn(Opcodes.NEW, "C")
+ .astore(1)
+ .aconst_null()
+ .aload(0)
+ .aload(1)
+ .insn(Opcodes.DUP2_X1)
+ .insn(Opcodes.POP2)
+ .insn(Opcodes.POP)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #10.
+ // After instrumentation, expect an after advice here, before instruction #10.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(10).withAfterAdviceAt(10).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithDup2X2() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 6, 2)
+ .typeInsn(Opcodes.NEW, "C")
+ .astore(1)
+ .insn(Opcodes.LCONST_0)
+ .aload(0)
+ .aload(1)
+ .insn(Opcodes.DUP2_X2)
+ .insn(Opcodes.POP2)
+ .insn(Opcodes.POP2)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #10.
+ // After instrumentation, expect an after advice here, before instruction #10.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(10).withAfterAdviceAt(10).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithJsrRet() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 3)
+ .trycatch(label0, label1, label1)
+ .label(label0)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #3.
+ .go(label3)
+ .label(label1)
+ .jsr(label2)
+ // After instrumentation, expect an after advice here, before instruction #6.
+ .athrow()
+ .label(label2)
+ .astore(2)
+ .ret(2)
+ .label(label3)
+ // After instrumentation, expect an after advice here, before instruction #11.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(3)
+ .withAfterAdviceAt(6, 11)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithLongsAndArrays() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 6, 4)
+ .aload(0)
+ .typeInsn(Opcodes.NEW, "C")
+ .fieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "MAX_VALUE", "J")
+ .varInsn(Opcodes.LSTORE, 2)
+ .insn(Opcodes.ICONST_1)
+ .intInsn(Opcodes.NEWARRAY, Opcodes.T_LONG)
+ .iconst_0()
+ .ldcInsn(123L)
+ .insn(Opcodes.LASTORE)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, DON'T expect a before advice here, because the above call does
+ // not initialize 'this'.
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #11.
+ // After instrumentation, expect an after advice here, before instruction #11.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(11).withAfterAdviceAt(11).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithMultiAnewArray() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 2)
+ .aload(0)
+ .insn(Opcodes.ICONST_1)
+ .insn(Opcodes.ICONST_2)
+ .multiANewArrayInsn("[[I", 2)
+ .fieldInsn(Opcodes.PUTSTATIC, "C", "f", "[[I")
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #6.
+ // After instrumentation, expect an after advice here, before instruction #6.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(6).withAfterAdviceAt(6).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithBranchesAfterSuperInit() {
+ Label label1 = new Label();
+ Label label2 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 2, 2)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #2.
+ .go(label1)
+ .label(label2)
+ .insn(Opcodes.POP)
+ // After instrumentation, expect an after advice here, before instruction #5.
+ .vreturn()
+ .label(label1)
+ .iconst_0()
+ .go(label2)
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(2).withAfterAdviceAt(5).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithForwardGotoAfterBlockWithoutSuccessor() {
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 2)
+ .trycatch(label1, label2, label2)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #2.
+ .label(label1)
+ .iconst_0()
+ .go(label3)
+ .label(label2)
+ // After instrumentation, expect an after advice here, before instruction #6.
+ .athrow()
+ .label(label3)
+ .pop()
+ // After instrumentation, expect an after advice here, before instruction #9.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(2)
+ .withAfterAdviceAt(6)
+ .withAfterAdviceAt(9)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"lookupswitch", "tableswitch"})
+ void testAllMethods_constructorWithForwardSwitchAfterBlockWithoutSuccessor(
+ final String parameter) {
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 3, 2)
+ .trycatch(label1, label2, label2)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #2.
+ .label(label1)
+ .iconst_0()
+ .iconst_0()
+ .switchto(label3, label3, /*useTableSwitch=*/ parameter.equals("tableswitch"))
+ .label(label2)
+ // After instrumentation, expect an after advice here, before instruction #7.
+ .athrow()
+ .label(label3)
+ .pop()
+ // After instrumentation, expect an after advice here, before instruction #10.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod)
+ .withBeforeAdviceAt(2)
+ .withAfterAdviceAt(7)
+ .withAfterAdviceAt(10)
+ .build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @Test
+ void testAllMethods_constructorWithHandlerFallthroughToPrivateMethodCall() {
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+ MethodNode inputMethod =
+ new MethodNodeBuilder("<init>", "(I)V", 2, 2)
+ .trycatch(label1, label2, label2)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
+ // After instrumentation, expect a before advice here, before instruction #2.
+ .label(label1)
+ .go(label3)
+ .label(label2)
+ .astore(1)
+ .label(label3)
+ .aload(0)
+ .methodInsn(Opcodes.INVOKESPECIAL, "C", "privateMethod", "()V", false)
+ // After instrumentation, expect an after advice here, before instruction #9.
+ .vreturn()
+ .build();
+
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ inputMethod.accept(new BasicAdviceAdapter(outputMethod));
+
+ MethodNode expectedMethod =
+ new ExpectedMethodBuilder(inputMethod).withBeforeAdviceAt(2).withAfterAdviceAt(9).build();
+ assertEquals(toText(expectedMethod), toText(outputMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(outputMethod).newInstance());
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) throws Exception {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor adviceClassAdapter =
+ new EmptyAdviceClassAdapter(apiParameter.value(), classWriter);
+
+ Executable accept = () -> classReader.accept(adviceClassAdapter, ClassReader.EXPAND_FRAMES);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ return;
+ }
+ assertDoesNotThrow(accept);
+ ClassWriter expectedClassWriter = new ClassWriter(0);
+ ClassVisitor expectedClassVisitor =
+ new LocalVariablesSorterTest.LocalVariablesSorterClassAdapter(
+ apiParameter.value(), expectedClassWriter);
+ classReader.accept(expectedClassVisitor, ClassReader.EXPAND_FRAMES);
+ assertEquals(
+ new ClassFile(expectedClassWriter.toByteArray()), new ClassFile(classWriter.toByteArray()));
+ }
+
+ @Test
+ void testOnMethodEnter_mixedVisitors() {
+ MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
+ AdviceAdapter adviceAdapter =
+ new AdviceAdapter(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL,
+ new MethodVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL, outputMethod) {},
+ Opcodes.ACC_PUBLIC,
+ "<init>",
+ "()V") {
+ @Override
+ protected void onMethodEnter() {
+ Label label = new Label();
+ visitLabel(label);
+ // Generate ICONST_1 with the delegate visitor. The advice adapter does not 'see' this
+ // and therefore cannot update its stack state, if it were doing so.
+ mv.visitInsn(ICONST_1);
+ // Generate IFEQ with the advice adapter itself. If the stack was updated here, it would
+ // pop from an empty stack because the previous ICONST_1 was not simulated.
+ visitJumpInsn(IFEQ, label);
+ }
+
+ @Override
+ protected void onMethodExit(final int opcode) {}
+ };
+
+ adviceAdapter.visitCode();
+ adviceAdapter.visitVarInsn(Opcodes.ALOAD, 0);
+ adviceAdapter.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ adviceAdapter.visitInsn(Opcodes.RETURN);
+ adviceAdapter.visitMaxs(0, 0);
+ adviceAdapter.visitEnd();
+
+ assertEquals(
+ " ALOAD 0\n"
+ + " INVOKESPECIAL java/lang/Object.<init> ()V\n"
+ + " L0\n"
+ + " ICONST_1\n"
+ + " IFEQ L0\n"
+ + " RETURN\n"
+ + " MAXSTACK = 0\n"
+ + " MAXLOCALS = 1\n",
+ toText(outputMethod));
+ }
+
+ private static InsnList newBasicAdvice(final boolean isAfterAdvice) {
+ InsnList insnList = new InsnList();
+ insnList.add(
+ new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"));
+ insnList.add(new LdcInsnNode(isAfterAdvice ? "exit" : "enter"));
+ insnList.add(
+ new MethodInsnNode(
+ Opcodes.INVOKEVIRTUAL,
+ "java/io/PrintStream",
+ "println",
+ "(Ljava/lang/String;)V",
+ /* isInterface= */ false));
+ return insnList;
+ }
+
+ private static class BasicAdviceAdapter extends AdviceAdapter {
+
+ BasicAdviceAdapter(final MethodVisitor methodVisitor) {
+ super(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL,
+ methodVisitor,
+ Opcodes.ACC_PUBLIC,
+ "<init>",
+ "(I)V");
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (value instanceof Boolean
+ || value instanceof Byte
+ || value instanceof Short
+ || value instanceof Character
+ || value instanceof Integer
+ || value instanceof Long
+ || value instanceof Double
+ || value instanceof Float
+ || value instanceof String
+ || value instanceof Type
+ || value instanceof Handle
+ || value instanceof ConstantDynamic) {
+ super.visitLdcInsn(value);
+ } else {
+ // If this happens, add support for the new type in AdviceAdapter.visitLdcInsn(), if needed.
+ throw new IllegalArgumentException("Unsupported type of value: " + value);
+ }
+ }
+
+ @Override
+ protected void onMethodEnter() {
+ newBasicAdvice(/* isAfterAdvice= */ false).accept(this);
+ }
+
+ @Override
+ protected void onMethodExit(final int opcode) {
+ newBasicAdvice(/* isAfterAdvice= */ true).accept(this);
+ }
+ }
+
+ private static class ExpectedMethodBuilder {
+
+ private final MethodNode inputMethod;
+ private final ArrayList<Advice> advices;
+
+ ExpectedMethodBuilder(final MethodNode inputMethod) {
+ this.inputMethod = inputMethod;
+ this.advices = new ArrayList<>();
+ }
+
+ ExpectedMethodBuilder withBeforeAdviceAt(final int... insnIndices) {
+ for (int insnIndex : insnIndices) {
+ advices.add(new Advice(insnIndex, /* isAfterAdvice= */ false));
+ }
+ return this;
+ }
+
+ ExpectedMethodBuilder withAfterAdviceAt(final int... insnIndices) {
+ for (int insnIndex : insnIndices) {
+ advices.add(new Advice(insnIndex, /* isAfterAdvice= */ true));
+ }
+ return this;
+ }
+
+ MethodNode build() {
+ MethodNode outputMethod =
+ new MethodNode(inputMethod.access, inputMethod.name, inputMethod.desc, null, null);
+ inputMethod.accept(outputMethod);
+
+ Collections.sort(advices);
+ for (Advice advice : advices) {
+ outputMethod.instructions.insertBefore(
+ outputMethod.instructions.get(advice.insnIndex), newBasicAdvice(advice.isAfterAdvice));
+ }
+ return outputMethod;
+ }
+
+ static class Advice implements Comparable<Advice> {
+
+ final int insnIndex;
+ final boolean isAfterAdvice;
+
+ Advice(final int insnIndex, final boolean isAfterAdvice) {
+ this.insnIndex = insnIndex;
+ this.isAfterAdvice = isAfterAdvice;
+ }
+
+ @Override
+ public int compareTo(final Advice other) {
+ if (other.insnIndex == insnIndex) {
+ return Boolean.compare(other.isAfterAdvice, isAfterAdvice);
+ } else {
+ return Integer.compare(other.insnIndex, insnIndex);
+ }
+ }
+ }
+ }
+
+ private static class EmptyAdviceClassAdapter extends ClassVisitor {
+
+ EmptyAdviceClassAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ if (methodVisitor == null || (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) > 0) {
+ return methodVisitor;
+ }
+ return new AdviceAdapter(api, methodVisitor, access, name, descriptor) {};
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java
new file mode 100644
index 00000000..9866c009
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java
@@ -0,0 +1,323 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link AnalyzerAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class AnalyzerAdapterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(
+ () -> new AnalyzerAdapter("pkg/Class", Opcodes.ACC_PUBLIC, "name", "()V", null));
+ assertThrows(
+ IllegalStateException.class,
+ () -> new AnalyzerAdapter("pkg/Class", Opcodes.ACC_PUBLIC, "name", "()V", null) {});
+ }
+
+ @Test
+ void testVisitFrame_emptyFrame() {
+ AnalyzerAdapter analyzerAdapter =
+ new AnalyzerAdapter("pkg/Class", Opcodes.ACC_PUBLIC, "name", "()V", null);
+
+ Executable visitFrame = () -> analyzerAdapter.visitFrame(Opcodes.F_NEW, 0, null, 0, null);
+
+ assertDoesNotThrow(visitFrame);
+ }
+
+ @Test
+ void testVisitFrame_invalidFrameType() {
+ AnalyzerAdapter analyzerAdapter =
+ new AnalyzerAdapter("pkg/Class", Opcodes.ACC_PUBLIC, "name", "()V", null);
+
+ Executable visitFrame = () -> analyzerAdapter.visitFrame(Opcodes.F_FULL, 0, null, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals(
+ "AnalyzerAdapter only accepts expanded frames (see ClassReader.EXPAND_FRAMES)",
+ exception.getMessage());
+ }
+
+ /**
+ * Tests that classes with additional frames inserted at each instruction, using the results of an
+ * AnalyzerAdapter, can be instantiated and loaded. This makes sure the intermediate frames
+ * computed by AnalyzerAdapter are correct, i.e. pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) throws Exception {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor classAnalyzerAdapter = new ClassAnalyzerAdapter(apiParameter.value(), classWriter);
+
+ Executable accept = () -> classReader.accept(classAnalyzerAdapter, ClassReader.EXPAND_FRAMES);
+
+ // jdk3.AllInstructions and jdk3.LargeMethod contain unsupported jsr/ret instructions.
+ if (classParameter == PrecompiledClass.JDK3_ALL_INSTRUCTIONS
+ || classParameter == PrecompiledClass.JDK3_LARGE_METHOD) {
+ Exception exception = assertThrows(IllegalArgumentException.class, accept);
+ assertEquals("JSR/RET are not supported", exception.getMessage());
+ } else if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ Executable newInstance = () -> new ClassFile(classWriter.toByteArray()).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+ }
+
+ /**
+ * A ClassVisitor that inserts intermediate frames before each instruction of each method, using
+ * the types computed with an AnalyzerAdapter (in order to check that these intermediate frames
+ * are correct).
+ */
+ static class ClassAnalyzerAdapter extends ClassVisitor {
+
+ private String owner;
+
+ ClassAnalyzerAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ owner = name;
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ AnalyzedFramesInserter inserter = new AnalyzedFramesInserter(methodVisitor);
+ AnalyzerAdapter analyzerAdapter =
+ new AnalyzerAdapter(api, owner, access, name, descriptor, inserter) {
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ // AnalyzerAdapter should correctly recompute maxLocals from scratch.
+ super.visitMaxs(maxStack, 0);
+ }
+ };
+ inserter.setAnalyzerAdapter(analyzerAdapter);
+ return analyzerAdapter;
+ }
+ }
+
+ /**
+ * Inserts intermediate frames before each instruction, using the types computed with an
+ * AnalyzerAdapter.
+ */
+ static class AnalyzedFramesInserter extends MethodVisitor {
+
+ private AnalyzerAdapter analyzerAdapter;
+ private boolean hasOriginalFrame;
+
+ AnalyzedFramesInserter(final MethodVisitor methodVisitor) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, methodVisitor);
+ }
+
+ void setAnalyzerAdapter(final AnalyzerAdapter analyzerAdapter) {
+ this.analyzerAdapter = analyzerAdapter;
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ super.visitFrame(type, numLocal, local, numStack, stack);
+ hasOriginalFrame = true;
+ }
+
+ private void maybeInsertFrame() {
+ // Don't insert a frame if we already have one for this instruction, from the original class.
+ if (!hasOriginalFrame) {
+ if (analyzerAdapter.locals != null && analyzerAdapter.stack != null) {
+ ArrayList<Object> local = toFrameTypes(analyzerAdapter.locals);
+ ArrayList<Object> stack = toFrameTypes(analyzerAdapter.stack);
+ super.visitFrame(
+ Opcodes.F_NEW, local.size(), local.toArray(), stack.size(), stack.toArray());
+ }
+ }
+ hasOriginalFrame = false;
+ }
+
+ /**
+ * Converts local and stack types from AnalyzerAdapter to visitFrame format (long and double are
+ * represented with one element in visitFrame, but with two elements in AnalyzerAdapter).
+ */
+ private ArrayList<Object> toFrameTypes(final List<Object> analyzerTypes) {
+ ArrayList<Object> frameTypes = new ArrayList<>();
+ for (int i = 0; i < analyzerTypes.size(); ++i) {
+ if (i > 0
+ && (analyzerTypes.get(i - 1) == Opcodes.LONG
+ || analyzerTypes.get(i - 1) == Opcodes.DOUBLE)) {
+ continue;
+ }
+ Object value = analyzerTypes.get(i);
+ frameTypes.add(value);
+ }
+ return frameTypes;
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ maybeInsertFrame();
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ maybeInsertFrame();
+ super.visitIntInsn(opcode, operand);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ maybeInsertFrame();
+ super.visitVarInsn(opcode, varIndex);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ maybeInsertFrame();
+ super.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ maybeInsertFrame();
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ maybeInsertFrame();
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ maybeInsertFrame();
+ super.visitInvokeDynamicInsn(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ maybeInsertFrame();
+ super.visitJumpInsn(opcode, label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ maybeInsertFrame();
+ super.visitLdcInsn(value);
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ maybeInsertFrame();
+ super.visitIincInsn(varIndex, increment);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ maybeInsertFrame();
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ maybeInsertFrame();
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ maybeInsertFrame();
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java
new file mode 100644
index 00000000..697125f3
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java
@@ -0,0 +1,425 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Locale;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.util.CheckMethodAdapter;
+
+/**
+ * Unit tests for {@link ClassRemapper}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassRemapperTest extends AsmTest {
+
+ @Test
+ void testVisit() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper classRemapper =
+ new ClassRemapper(classNode, new SimpleRemapper("pkg/C", "new/pkg/C"));
+
+ classRemapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
+
+ assertEquals("new/pkg/C", classNode.name);
+ }
+
+ @Test
+ void testVisitAnnotation() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper remapper =
+ new ClassRemapper(
+ classNode,
+ new Remapper() {
+ @Override
+ public String mapAnnotationAttributeName(final String descriptor, final String name) {
+ if ("Lpkg/A;".equals(descriptor)) {
+ return "new." + name;
+ }
+ return name;
+ }
+ });
+ remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
+ AnnotationVisitor annotationVisitor = remapper.visitAnnotation("Lpkg/A;", true);
+ annotationVisitor.visit("attribute", "value");
+
+ assertEquals("new.attribute", classNode.visibleAnnotations.get(0).values.get(0));
+ }
+
+ @Test
+ void testVisitInnerClass() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper remapper =
+ new ClassRemapper(
+ classNode,
+ new Remapper() {
+ @Override
+ public String map(final String internalName) {
+ if ("pkg/C".equals(internalName)) {
+ return "a";
+ }
+ if ("pkg/C$Inner".equals(internalName)) {
+ return "a$b";
+ }
+ return internalName;
+ }
+ });
+ remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
+
+ remapper.visitInnerClass("pkg/C$Inner", "pkg/C", "Inner", Opcodes.ACC_PUBLIC);
+
+ assertEquals("a$b", classNode.innerClasses.get(0).name);
+ assertEquals("a", classNode.innerClasses.get(0).outerName);
+ assertEquals("b", classNode.innerClasses.get(0).innerName);
+ }
+
+ @Test
+ void testVisitInnerClass_localInnerClass() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper remapper =
+ new ClassRemapper(
+ classNode,
+ new Remapper() {
+ @Override
+ public String map(final String internalName) {
+ if ("pkg/C".equals(internalName)) {
+ return "a";
+ }
+ if ("pkg/C$1Inner".equals(internalName)) {
+ return "a$1b";
+ }
+ return internalName;
+ }
+ });
+ remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
+
+ remapper.visitInnerClass("pkg/C$1Inner", "pkg/C", "Inner", Opcodes.ACC_PUBLIC);
+
+ assertEquals("a$1b", classNode.innerClasses.get(0).name);
+ assertEquals("a", classNode.innerClasses.get(0).outerName);
+ assertEquals("b", classNode.innerClasses.get(0).innerName);
+ }
+
+ @Test
+ void testVisitInnerClass_specialRemap() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper remapper =
+ new ClassRemapper(
+ classNode,
+ new Remapper() {
+ @Override
+ public String map(final String internalName) {
+ if ("pkg/C".equals(internalName)) {
+ return "pkg2/C";
+ }
+ if ("pkg/C$$a".equals(internalName)) {
+ return "pkg2/C$$a";
+ }
+ return internalName;
+ }
+ });
+ remapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "pkg/C", null, "java/lang/Object", null);
+
+ remapper.visitInnerClass("pkg/C$$a", "pkg/C", "$a", Opcodes.ACC_PUBLIC);
+
+ assertEquals("pkg2/C$$a", classNode.innerClasses.get(0).name);
+ assertEquals("pkg2/C", classNode.innerClasses.get(0).outerName);
+ assertEquals("$a", classNode.innerClasses.get(0).innerName);
+ }
+
+ @Test
+ void testVisitAttribute_moduleHashes() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper classRemapper =
+ new ClassRemapper(
+ classNode,
+ new Remapper() {
+ @Override
+ public String mapModuleName(final String name) {
+ return "new." + name;
+ }
+ });
+ classRemapper.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ classRemapper.visitAttribute(
+ new ModuleHashesAttribute("algorithm", Arrays.asList("pkg.C"), Arrays.asList(new byte[0])));
+
+ assertEquals("C", classNode.name);
+ assertEquals("new.pkg.C", ((ModuleHashesAttribute) classNode.attrs.get(0)).modules.get(0));
+ }
+
+ @Test
+ void testVisitLdcInsn_constantDynamic() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper classRemapper =
+ new ClassRemapper(
+ /* latest api */ Opcodes.ASM9,
+ classNode,
+ new Remapper() {
+ @Override
+ public String mapInvokeDynamicMethodName(final String name, final String descriptor) {
+ return "new." + name;
+ }
+
+ @Override
+ public String map(final String internalName) {
+ if (internalName.equals("java/lang/String")) {
+ return "java/lang/Integer";
+ }
+ return internalName;
+ }
+ }) {
+ /* inner class so it can access the protected constructor */
+ };
+ classRemapper.visit(Opcodes.V11, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ classRemapper.visitMethod(Opcodes.ACC_PUBLIC, "hello", "()V", null, null);
+ methodVisitor.visitCode();
+
+ methodVisitor.visitLdcInsn(
+ new ConstantDynamic(
+ "foo",
+ "Ljava/lang/String;",
+ new Handle(Opcodes.H_INVOKESTATIC, "BSMHost", "bsm", "()Ljava/lang/String;", false)));
+
+ ConstantDynamic constantDynamic =
+ (ConstantDynamic) ((LdcInsnNode) classNode.methods.get(0).instructions.get(0)).cst;
+ assertEquals("new.foo", constantDynamic.getName());
+ assertEquals("Ljava/lang/Integer;", constantDynamic.getDescriptor());
+ assertEquals("()Ljava/lang/Integer;", constantDynamic.getBootstrapMethod().getDesc());
+ }
+
+ @Test
+ void testInvokeDynamicInsn_field() {
+ ClassNode classNode = new ClassNode();
+ ClassRemapper classRemapper =
+ new ClassRemapper(
+ /* latest api */ Opcodes.ASM9,
+ classNode,
+ new Remapper() {
+ @Override
+ public String mapFieldName(
+ final String owner, final String name, final String descriptor) {
+ if ("a".equals(name)) {
+ return "demo";
+ }
+ return name;
+ }
+ });
+ classRemapper.visit(Opcodes.V11, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ classRemapper.visitMethod(Opcodes.ACC_PUBLIC, "hello", "()V", null, null);
+ methodVisitor.visitCode();
+
+ methodVisitor.visitInvokeDynamicInsn(
+ "foo",
+ "()Ljava/lang/String;",
+ new Handle(Opcodes.H_GETFIELD, "pkg/B", "a", "Ljava/lang/String;", false));
+
+ InvokeDynamicInsnNode invokeDynamic =
+ (InvokeDynamicInsnNode) classNode.methods.get(0).instructions.get(0);
+ assertEquals("demo", invokeDynamic.bsm.getName());
+ }
+
+ /** Tests that classes transformed with a ClassRemapper can be loaded and instantiated. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+ UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName());
+ ClassRemapper classRemapper =
+ newClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper);
+
+ Executable accept = () -> classReader.accept(classRemapper, 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ Executable newInstance = () -> new ClassFile(classWriter.toByteArray()).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+ }
+
+ /**
+ * Tests that classes transformed with a ClassNode and ClassRemapper can be loaded and
+ * instantiated.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass_fromClassNode(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classParameter.getBytes()).accept(classNode, 0);
+ ClassWriter classWriter = new ClassWriter(0);
+ UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName());
+ ClassRemapper classRemapper =
+ newClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper);
+
+ Executable accept = () -> classNode.accept(classRemapper);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ Executable newInstance = () -> new ClassFile(classWriter.toByteArray()).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+ }
+
+ private static void checkDescriptor(final String descriptor) {
+ CheckMethodAdapter checkMethodAdapter = new CheckMethodAdapter(null);
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitFieldInsn(Opcodes.GETFIELD, "Owner", "name", descriptor);
+ }
+
+ private static void checkInternalName(final String internalName) {
+ CheckMethodAdapter checkMethodAdapter = new CheckMethodAdapter(null);
+ checkMethodAdapter.version = Opcodes.V1_5;
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitFieldInsn(Opcodes.GETFIELD, internalName, "name", "I");
+ }
+
+ ClassRemapper newClassRemapper(
+ final int api, final ClassVisitor classVisitor, final Remapper remapper) {
+ return new ClassRemapper(api, classVisitor, remapper);
+ }
+
+ static class UpperCaseRemapper extends Remapper {
+
+ private static final Locale LOCALE = Locale.ENGLISH;
+
+ private final String internalClassName;
+ private final String remappedInternalClassName;
+
+ UpperCaseRemapper(final String internalClassName) {
+ this.internalClassName = internalClassName;
+ this.remappedInternalClassName =
+ internalClassName.equals("module-info")
+ ? internalClassName
+ : internalClassName.toUpperCase(LOCALE);
+ }
+
+ String getRemappedClassName() {
+ return remappedInternalClassName.replace('/', '.');
+ }
+
+ @Override
+ public String mapDesc(final String descriptor) {
+ checkDescriptor(descriptor);
+ return super.mapDesc(descriptor);
+ }
+
+ @Override
+ public String mapType(final String type) {
+ if (type != null && !type.equals("module-info")) {
+ checkInternalName(type);
+ }
+ return super.mapType(type);
+ }
+
+ @Override
+ public String mapMethodName(final String owner, final String name, final String descriptor) {
+ if (name.equals("<init>") || name.equals("<clinit>")) {
+ return name;
+ }
+ return owner.equals(internalClassName) ? name.toUpperCase(LOCALE) : name;
+ }
+
+ @Override
+ public String mapInvokeDynamicMethodName(final String name, final String descriptor) {
+ return name.toUpperCase(LOCALE);
+ }
+
+ @Override
+ public String mapFieldName(final String owner, final String name, final String descriptor) {
+ return owner.equals(internalClassName) ? name.toUpperCase(LOCALE) : name;
+ }
+
+ @Override
+ public String map(final String typeName) {
+ return typeName.equals(internalClassName) ? remappedInternalClassName : typeName;
+ }
+
+ @Override
+ public Object mapValue(final Object value) {
+ if (value instanceof Boolean
+ || value instanceof Byte
+ || value instanceof Short
+ || value instanceof Character
+ || value instanceof Integer
+ || value instanceof Long
+ || value instanceof Double
+ || value instanceof Float
+ || value instanceof String
+ || value instanceof Type
+ || value instanceof Handle
+ || value instanceof ConstantDynamic
+ || value.getClass().isArray()) {
+ return super.mapValue(value);
+ }
+ // If this happens, add support for the new type in Remapper.mapValue(), if needed.
+ throw new IllegalArgumentException("Unsupported type of value: " + value);
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/CodeComment.java b/asm-commons/src/test/java/org/objectweb/asm/commons/CodeComment.java
new file mode 100644
index 00000000..f56ba446
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/CodeComment.java
@@ -0,0 +1,84 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard code attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class CodeComment extends Attribute {
+
+ public CodeComment() {
+ super("CodeComment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeOffset,
+ final Label[] labels) {
+
+ return new CodeComment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+
+ @Override
+ protected Label[] getLabels() {
+ super.getLabels();
+ return new Label[] {new Label()};
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/CodeSizeEvaluatorTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/CodeSizeEvaluatorTest.java
new file mode 100644
index 00000000..204c9782
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/CodeSizeEvaluatorTest.java
@@ -0,0 +1,161 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link CodeSizeEvaluator}.
+ *
+ * @author Eric Bruneton
+ */
+class CodeSizeEvaluatorTest extends AsmTest {
+
+ /**
+ * Tests that the size estimations of CodeSizeEvaluator are correct, and that classes are
+ * unchanged with a ClassReader->CodeSizeEvaluator->ClassWriter transform.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ArrayList<CodeSizeEvaluation> evaluations = new ArrayList<>();
+ ClassVisitor codeSizesEvaluator =
+ new CodeSizesEvaluator(apiParameter.value(), classWriter, evaluations);
+
+ Executable accept = () -> classReader.accept(codeSizesEvaluator, attributes(), 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ for (CodeSizeEvaluation evaluation : evaluations) {
+ assertTrue(evaluation.actualSize >= evaluation.minSize);
+ assertTrue(evaluation.actualSize <= evaluation.maxSize);
+ }
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+ }
+
+ private static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ static class CodeSizeEvaluation {
+
+ final int minSize;
+ final int maxSize;
+ final int actualSize;
+
+ CodeSizeEvaluation(final int minSize, final int maxSize, final int actualSize) {
+ this.minSize = minSize;
+ this.maxSize = maxSize;
+ this.actualSize = actualSize;
+ }
+ }
+
+ static class CodeSizesEvaluator extends ClassVisitor {
+
+ private final ArrayList<CodeSizeEvaluation> evaluations;
+
+ CodeSizesEvaluator(
+ final int api,
+ final ClassWriter classWriter,
+ final ArrayList<CodeSizeEvaluation> evaluations) {
+ super(api, classWriter);
+ this.evaluations = evaluations;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ return new CodeSizeEvaluator(api, methodVisitor) {
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (value instanceof Boolean
+ || value instanceof Byte
+ || value instanceof Short
+ || value instanceof Character
+ || value instanceof Integer
+ || value instanceof Long
+ || value instanceof Double
+ || value instanceof Float
+ || value instanceof String
+ || value instanceof Type
+ || value instanceof Handle
+ || value instanceof ConstantDynamic) {
+ super.visitLdcInsn(value);
+ } else {
+ // If this happens, add support for the new type in
+ // CodeSizeEvaluator.visitLdcInsn(), if needed.
+ throw new IllegalArgumentException("Unsupported type of value: " + value);
+ }
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ Label end = new Label();
+ visitLabel(end);
+ super.visitMaxs(maxStack, maxLocals);
+
+ evaluations.add(new CodeSizeEvaluation(getMinSize(), getMaxSize(), end.getOffset()));
+ }
+ };
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/Comment.java b/asm-commons/src/test/java/org/objectweb/asm/commons/Comment.java
new file mode 100644
index 00000000..4b3910a8
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/Comment.java
@@ -0,0 +1,72 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class Comment extends Attribute {
+
+ public Comment() {
+ super("Comment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeOffset,
+ final Label[] labels) {
+ return new Comment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java
new file mode 100644
index 00000000..c5ca9134
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java
@@ -0,0 +1,1259 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.objectweb.asm.commons.GeneratorAdapter.EQ;
+import static org.objectweb.asm.commons.GeneratorAdapter.GE;
+import static org.objectweb.asm.commons.GeneratorAdapter.GT;
+import static org.objectweb.asm.commons.GeneratorAdapter.LE;
+import static org.objectweb.asm.commons.GeneratorAdapter.LT;
+import static org.objectweb.asm.commons.GeneratorAdapter.NE;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.util.Textifier;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
+/**
+ * Unit tests for {@link GeneratorAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class GeneratorAdapterTest {
+
+ private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor =
+ () -> new GeneratorAdapter(new MethodNode(), Opcodes.ACC_PUBLIC, "name", "()V") {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+
+ @Test
+ void testConstructor_emptyDescriptor() {
+ GeneratorAdapter generatorAdapter =
+ new GeneratorAdapter(new MethodNode(), Opcodes.ACC_PUBLIC, "name", "()V");
+
+ assertEquals(Opcodes.ACC_PUBLIC, generatorAdapter.getAccess());
+ assertEquals("name", generatorAdapter.getName());
+ assertEquals(Type.VOID_TYPE, generatorAdapter.getReturnType());
+ assertArrayEquals(new Type[0], generatorAdapter.getArgumentTypes());
+ }
+
+ @Test
+ void testConstructor_basicDescriptor() {
+ GeneratorAdapter generatorAdapter =
+ new GeneratorAdapter(new MethodNode(), Opcodes.ACC_PRIVATE, "m", "(I)F");
+
+ assertEquals(Opcodes.ACC_PRIVATE, generatorAdapter.getAccess());
+ assertEquals("m", generatorAdapter.getName());
+ assertEquals(Type.FLOAT_TYPE, generatorAdapter.getReturnType());
+ assertArrayEquals(new Type[] {Type.INT_TYPE}, generatorAdapter.getArgumentTypes());
+ }
+
+ @Test
+ void testConstructor_withClassVisitorAndExceptions() {
+ ClassNode classNode = new ClassNode();
+
+ GeneratorAdapter generatorAdapter =
+ new GeneratorAdapter(
+ Opcodes.ACC_PUBLIC,
+ new Method("name", "()V"),
+ "()V",
+ new Type[] {Type.getObjectType("java/lang/Exception")},
+ classNode);
+
+ assertEquals(Opcodes.ACC_PUBLIC, generatorAdapter.getAccess());
+ assertEquals("name", generatorAdapter.getName());
+ assertEquals(Type.VOID_TYPE, generatorAdapter.getReturnType());
+ assertArrayEquals(new Type[0], generatorAdapter.getArgumentTypes());
+ MethodNode methodNode = classNode.methods.get(0);
+ assertEquals(Opcodes.ACC_PUBLIC, methodNode.access);
+ assertEquals("name", methodNode.name);
+ assertEquals("()V", methodNode.desc);
+ assertEquals(Arrays.asList("java/lang/Exception"), methodNode.exceptions);
+ }
+
+ @Test
+ void testConstructor_withClassVisitorAndNoExceptions() {
+ ClassNode classNode = new ClassNode();
+
+ GeneratorAdapter generatorAdapter =
+ new GeneratorAdapter(Opcodes.ACC_PUBLIC, new Method("name", "()V"), "()V", null, classNode);
+
+ assertEquals(Opcodes.ACC_PUBLIC, generatorAdapter.getAccess());
+ assertEquals("name", generatorAdapter.getName());
+ assertEquals(Type.VOID_TYPE, generatorAdapter.getReturnType());
+ assertArrayEquals(new Type[0], generatorAdapter.getArgumentTypes());
+ MethodNode methodNode = classNode.methods.get(0);
+ assertEquals(Opcodes.ACC_PUBLIC, methodNode.access);
+ assertEquals("name", methodNode.name);
+ assertEquals("()V", methodNode.desc);
+ assertEquals(Arrays.asList(), methodNode.exceptions);
+ }
+
+ @Test
+ void testPush_boolean() {
+ assertEquals("ICONST_0", new Generator().push(false));
+ assertEquals("ICONST_1", new Generator().push(true));
+ }
+
+ @Test
+ void testPush_int() {
+ assertEquals("LDC -32769", new Generator().push(-32769));
+ assertEquals("SIPUSH -32768", new Generator().push(-32768));
+ assertEquals("BIPUSH -128", new Generator().push(-128));
+ assertEquals("ICONST_M1", new Generator().push(-1));
+ assertEquals("ICONST_0", new Generator().push(0));
+ assertEquals("ICONST_1", new Generator().push(1));
+ assertEquals("ICONST_2", new Generator().push(2));
+ assertEquals("ICONST_3", new Generator().push(3));
+ assertEquals("ICONST_4", new Generator().push(4));
+ assertEquals("ICONST_5", new Generator().push(5));
+ assertEquals("BIPUSH 6", new Generator().push(6));
+ assertEquals("BIPUSH 127", new Generator().push(127));
+ assertEquals("SIPUSH 128", new Generator().push(128));
+ assertEquals("SIPUSH 32767", new Generator().push(32767));
+ assertEquals("LDC 32768", new Generator().push(32768));
+ }
+
+ @Test
+ void testPush_long() {
+ assertEquals("LCONST_0", new Generator().push(0L));
+ assertEquals("LCONST_1", new Generator().push(1L));
+ assertEquals("LDC 2", new Generator().push(2L));
+ }
+
+ @Test
+ void testPush_float() {
+ assertEquals("FCONST_0", new Generator().push(0.0f));
+ assertEquals("FCONST_1", new Generator().push(1.0f));
+ assertEquals("FCONST_2", new Generator().push(2.0f));
+ assertEquals("LDC 3.0", new Generator().push(3.0f));
+ }
+
+ @Test
+ void testPush_double() {
+ assertEquals("DCONST_0", new Generator().push(0.0));
+ assertEquals("DCONST_1", new Generator().push(1.0));
+ assertEquals("LDC 2.0", new Generator().push(2.0));
+ }
+
+ @Test
+ void testPush_string() {
+ assertEquals("ACONST_NULL", new Generator().push((String) null));
+ assertEquals("LDC \"string\"", new Generator().push("string"));
+ }
+
+ @Test
+ void testPush_type() {
+ assertEquals("ACONST_NULL", new Generator().push((Type) null));
+ assertEquals(
+ "GETSTATIC java/lang/Boolean.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.BOOLEAN_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Character.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.CHAR_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Byte.TYPE : Ljava/lang/Class;", new Generator().push(Type.BYTE_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Short.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.SHORT_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Integer.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.INT_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Float.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.FLOAT_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Long.TYPE : Ljava/lang/Class;", new Generator().push(Type.LONG_TYPE));
+ assertEquals(
+ "GETSTATIC java/lang/Double.TYPE : Ljava/lang/Class;",
+ new Generator().push(Type.DOUBLE_TYPE));
+ assertEquals("LDC Ljava/lang/Object;.class", new Generator().push(OBJECT_TYPE));
+ assertEquals("LDC [I.class", new Generator().push(Type.getObjectType("[I")));
+ }
+
+ @Test
+ void testPush_handle() {
+ assertEquals("ACONST_NULL", new Generator().push((Handle) null));
+ assertEquals(
+ "LDC pkg/Owner.nameI (2)",
+ new Generator().push(new Handle(Opcodes.H_GETSTATIC, "pkg/Owner", "name", "I", false)));
+ }
+
+ @Test
+ void testLoadThis() {
+ assertEquals("ALOAD 0", new Generator().loadThis());
+ }
+
+ @Test
+ void testLoadThis_illegalState() {
+ Generator generator = new Generator(Opcodes.ACC_STATIC, "m", "()V");
+
+ Executable loadThis = () -> generator.loadThis();
+
+ assertThrows(IllegalStateException.class, loadThis);
+ }
+
+ @Test
+ void testLoadArg() {
+ assertEquals("ILOAD 1", new Generator(Opcodes.ACC_PUBLIC, "m", "(I)V").loadArg(0));
+ assertEquals("LLOAD 0", new Generator(Opcodes.ACC_STATIC, "m", "(J)V").loadArg(0));
+ assertEquals("FLOAD 2", new Generator(Opcodes.ACC_STATIC, "m", "(JF)V").loadArg(1));
+ }
+
+ @Test
+ void testLoadArgs() {
+ assertEquals("LLOAD 2", new Generator(Opcodes.ACC_PUBLIC, "m", "(IJFD)V").loadArgs(1, 1));
+ assertEquals(
+ "ILOAD 0 LLOAD 1 FLOAD 3 DLOAD 4",
+ new Generator(Opcodes.ACC_STATIC, "m", "(IJFD)V").loadArgs());
+ }
+
+ @Test
+ void testLoadArgArray() {
+ assertEquals(
+ "BIPUSH 9 ANEWARRAY java/lang/Object "
+ + "DUP ICONST_0 ILOAD 1 NEW java/lang/Boolean DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Boolean.<init> (Z)V AASTORE "
+ + "DUP ICONST_1 ILOAD 2 NEW java/lang/Byte DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Byte.<init> (B)V AASTORE "
+ + "DUP ICONST_2 ILOAD 3 NEW java/lang/Character DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Character.<init> (C)V AASTORE "
+ + "DUP ICONST_3 ILOAD 4 NEW java/lang/Short DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Short.<init> (S)V AASTORE "
+ + "DUP ICONST_4 ILOAD 5 NEW java/lang/Integer DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Integer.<init> (I)V AASTORE "
+ + "DUP ICONST_5 LLOAD 6 NEW java/lang/Long DUP_X2 DUP_X2 POP"
+ + " INVOKESPECIAL java/lang/Long.<init> (J)V AASTORE "
+ + "DUP BIPUSH 6 FLOAD 8 NEW java/lang/Float DUP_X1 SWAP"
+ + " INVOKESPECIAL java/lang/Float.<init> (F)V AASTORE "
+ + "DUP BIPUSH 7 DLOAD 9 NEW java/lang/Double DUP_X2 DUP_X2 POP"
+ + " INVOKESPECIAL java/lang/Double.<init> (D)V AASTORE "
+ + "DUP BIPUSH 8 ALOAD 11 AASTORE",
+ new Generator(Opcodes.ACC_PUBLIC, "m", "(ZBCSIJFDLjava/lang/Object;)V").loadArgArray());
+ }
+
+ @Test
+ void testStoreArg() {
+ assertEquals("ISTORE 1", new Generator(Opcodes.ACC_PUBLIC, "m", "(I)V").storeArg(0));
+ assertEquals("LSTORE 0", new Generator(Opcodes.ACC_STATIC, "m", "(J)V").storeArg(0));
+ assertEquals("FSTORE 2", new Generator(Opcodes.ACC_STATIC, "m", "(JF)V").storeArg(1));
+ }
+
+ @Test
+ void testNewLocal() {
+ Generator generator = new Generator();
+
+ int local = generator.newLocal(Type.FLOAT_TYPE);
+
+ assertEquals(Type.FLOAT_TYPE, generator.getLocalType(local));
+ }
+
+ @Test
+ void testLoadLocal() {
+ Generator generator = new Generator();
+ int local = generator.newLocal(Type.FLOAT_TYPE);
+
+ String loadLocal = generator.loadLocal(local);
+
+ assertEquals("FLOAD 1", loadLocal);
+ }
+
+ @Test
+ void testLoadLocal_withType() {
+ Generator generator = new Generator();
+ int local = generator.newLocal(Type.FLOAT_TYPE);
+
+ String loadLocal = generator.loadLocal(local, Type.INT_TYPE);
+
+ assertEquals("ILOAD 1", loadLocal);
+ assertEquals(Type.INT_TYPE, generator.getLocalType(local));
+ }
+
+ @Test
+ void testStoreLocal() {
+ Generator generator = new Generator();
+ int local = generator.newLocal(Type.FLOAT_TYPE);
+
+ String storeLocal = generator.storeLocal(local);
+
+ assertEquals("FSTORE 1", storeLocal);
+ }
+
+ @Test
+ void testStoreLocal_withType() {
+ Generator generator = new Generator();
+ int local = generator.newLocal(Type.FLOAT_TYPE);
+
+ String storeLocal = generator.storeLocal(local, Type.INT_TYPE);
+
+ assertEquals("ISTORE 1", storeLocal);
+ assertEquals(Type.INT_TYPE, generator.getLocalType(local));
+ }
+
+ @Test
+ void testArrayLoad() {
+ assertEquals("IALOAD", new Generator().arrayLoad(Type.INT_TYPE));
+ assertEquals("LALOAD", new Generator().arrayLoad(Type.LONG_TYPE));
+ }
+
+ @Test
+ void testArrayStore() {
+ assertEquals("IASTORE", new Generator().arrayStore(Type.INT_TYPE));
+ assertEquals("LASTORE", new Generator().arrayStore(Type.LONG_TYPE));
+ }
+
+ @Test
+ void testPop() {
+ assertEquals("POP", new Generator().pop());
+ }
+
+ @Test
+ void testPop2() {
+ assertEquals("POP2", new Generator().pop2());
+ }
+
+ @Test
+ void testDup() {
+ assertEquals("DUP", new Generator().dup());
+ }
+
+ @Test
+ void testDup2() {
+ assertEquals("DUP2", new Generator().dup2());
+ }
+
+ @Test
+ void testDupX1() {
+ assertEquals("DUP_X1", new Generator().dupX1());
+ }
+
+ @Test
+ void testDupX2() {
+ assertEquals("DUP_X2", new Generator().dupX2());
+ }
+
+ @Test
+ void testDup2X1() {
+ assertEquals("DUP2_X1", new Generator().dup2X1());
+ }
+
+ @Test
+ void testDup2X2() {
+ assertEquals("DUP2_X2", new Generator().dup2X2());
+ }
+
+ @Test
+ void testSwap() {
+ assertEquals("SWAP", new Generator().swap());
+ assertEquals("SWAP", new Generator().swap(Type.INT_TYPE, Type.INT_TYPE));
+ assertEquals("DUP_X2 POP", new Generator().swap(Type.LONG_TYPE, Type.INT_TYPE));
+ assertEquals("DUP2_X1 POP2", new Generator().swap(Type.INT_TYPE, Type.LONG_TYPE));
+ assertEquals("DUP2_X2 POP2", new Generator().swap(Type.LONG_TYPE, Type.LONG_TYPE));
+ }
+
+ @Test
+ void testMath() {
+ assertEquals("IADD", new Generator().math(GeneratorAdapter.ADD, Type.INT_TYPE));
+ assertEquals("FSUB", new Generator().math(GeneratorAdapter.SUB, Type.FLOAT_TYPE));
+ assertEquals("LMUL", new Generator().math(GeneratorAdapter.MUL, Type.LONG_TYPE));
+ assertEquals("DDIV", new Generator().math(GeneratorAdapter.DIV, Type.DOUBLE_TYPE));
+ assertEquals("IREM", new Generator().math(GeneratorAdapter.REM, Type.INT_TYPE));
+ assertEquals("LNEG", new Generator().math(GeneratorAdapter.NEG, Type.LONG_TYPE));
+ assertEquals("ISHL", new Generator().math(GeneratorAdapter.SHL, Type.INT_TYPE));
+ assertEquals("LSHR", new Generator().math(GeneratorAdapter.SHR, Type.LONG_TYPE));
+ assertEquals("IUSHR", new Generator().math(GeneratorAdapter.USHR, Type.INT_TYPE));
+ assertEquals("LAND", new Generator().math(GeneratorAdapter.AND, Type.LONG_TYPE));
+ assertEquals("IOR", new Generator().math(GeneratorAdapter.OR, Type.INT_TYPE));
+ assertEquals("LXOR", new Generator().math(GeneratorAdapter.XOR, Type.LONG_TYPE));
+ }
+
+ @Test
+ void testNot() {
+ assertEquals("ICONST_1 IXOR", new Generator().not());
+ }
+
+ @Test
+ void testIinc() {
+ assertEquals("IINC 3 5", new Generator().iinc(3, 5));
+ }
+
+ @Test
+ void testCast() {
+ assertEquals("", new Generator().cast(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE));
+ assertEquals("D2F", new Generator().cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE));
+ assertEquals("D2L", new Generator().cast(Type.DOUBLE_TYPE, Type.LONG_TYPE));
+ assertEquals("D2I", new Generator().cast(Type.DOUBLE_TYPE, Type.INT_TYPE));
+ assertEquals("D2I I2B", new Generator().cast(Type.DOUBLE_TYPE, Type.BYTE_TYPE));
+ assertEquals("F2D", new Generator().cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE));
+ assertEquals("", new Generator().cast(Type.FLOAT_TYPE, Type.FLOAT_TYPE));
+ assertEquals("F2L", new Generator().cast(Type.FLOAT_TYPE, Type.LONG_TYPE));
+ assertEquals("F2I", new Generator().cast(Type.FLOAT_TYPE, Type.INT_TYPE));
+ assertEquals("F2I I2B", new Generator().cast(Type.FLOAT_TYPE, Type.BYTE_TYPE));
+ assertEquals("L2D", new Generator().cast(Type.LONG_TYPE, Type.DOUBLE_TYPE));
+ assertEquals("L2F", new Generator().cast(Type.LONG_TYPE, Type.FLOAT_TYPE));
+ assertEquals("", new Generator().cast(Type.LONG_TYPE, Type.LONG_TYPE));
+ assertEquals("L2I", new Generator().cast(Type.LONG_TYPE, Type.INT_TYPE));
+ assertEquals("L2I I2B", new Generator().cast(Type.LONG_TYPE, Type.BYTE_TYPE));
+ assertEquals("I2D", new Generator().cast(Type.INT_TYPE, Type.DOUBLE_TYPE));
+ assertEquals("I2F", new Generator().cast(Type.INT_TYPE, Type.FLOAT_TYPE));
+ assertEquals("I2L", new Generator().cast(Type.INT_TYPE, Type.LONG_TYPE));
+ assertEquals("", new Generator().cast(Type.INT_TYPE, Type.INT_TYPE));
+ assertEquals("I2B", new Generator().cast(Type.INT_TYPE, Type.BYTE_TYPE));
+ assertEquals("I2C", new Generator().cast(Type.INT_TYPE, Type.CHAR_TYPE));
+ assertEquals("I2S", new Generator().cast(Type.INT_TYPE, Type.SHORT_TYPE));
+ assertEquals("", new Generator().cast(Type.BYTE_TYPE, Type.INT_TYPE));
+ assertEquals("", new Generator().cast(Type.SHORT_TYPE, Type.INT_TYPE));
+ }
+
+ @Test
+ void testCast_fromVoid() {
+ Executable cast = () -> new Generator().cast(Type.VOID_TYPE, Type.INT_TYPE);
+
+ assertThrows(IllegalArgumentException.class, cast);
+ }
+
+ @Test
+ void testCast_toVoid() {
+ Executable cast = () -> new Generator().cast(Type.INT_TYPE, Type.VOID_TYPE);
+
+ assertThrows(IllegalArgumentException.class, cast);
+ }
+
+ @Test
+ void testBox() {
+ assertEquals("", new Generator().box(OBJECT_TYPE));
+ assertEquals("", new Generator().box(Type.getObjectType("[I")));
+ assertEquals("ACONST_NULL", new Generator().box(Type.VOID_TYPE));
+ assertEquals(
+ "NEW java/lang/Boolean DUP_X1 SWAP INVOKESPECIAL java/lang/Boolean.<init> (Z)V",
+ new Generator().box(Type.BOOLEAN_TYPE));
+ assertEquals(
+ "NEW java/lang/Byte DUP_X1 SWAP INVOKESPECIAL java/lang/Byte.<init> (B)V",
+ new Generator().box(Type.BYTE_TYPE));
+ assertEquals(
+ "NEW java/lang/Character DUP_X1 SWAP INVOKESPECIAL java/lang/Character.<init> (C)V",
+ new Generator().box(Type.CHAR_TYPE));
+ assertEquals(
+ "NEW java/lang/Short DUP_X1 SWAP INVOKESPECIAL java/lang/Short.<init> (S)V",
+ new Generator().box(Type.SHORT_TYPE));
+ assertEquals(
+ "NEW java/lang/Integer DUP_X1 SWAP INVOKESPECIAL java/lang/Integer.<init> (I)V",
+ new Generator().box(Type.INT_TYPE));
+ assertEquals(
+ "NEW java/lang/Long DUP_X2 DUP_X2 POP INVOKESPECIAL java/lang/Long.<init> (J)V",
+ new Generator().box(Type.LONG_TYPE));
+ assertEquals(
+ "NEW java/lang/Float DUP_X1 SWAP INVOKESPECIAL java/lang/Float.<init> (F)V",
+ new Generator().box(Type.FLOAT_TYPE));
+ assertEquals(
+ "NEW java/lang/Double DUP_X2 DUP_X2 POP INVOKESPECIAL java/lang/Double.<init> (D)V",
+ new Generator().box(Type.DOUBLE_TYPE));
+ }
+
+ @Test
+ void testValueOf() {
+ assertEquals("", new Generator().valueOf(OBJECT_TYPE));
+ assertEquals("", new Generator().valueOf(Type.getType("[I")));
+ assertEquals("ACONST_NULL", new Generator().valueOf(Type.VOID_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;",
+ new Generator().valueOf(Type.BOOLEAN_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Byte.valueOf (B)Ljava/lang/Byte;",
+ new Generator().valueOf(Type.BYTE_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Character.valueOf (C)Ljava/lang/Character;",
+ new Generator().valueOf(Type.CHAR_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Short.valueOf (S)Ljava/lang/Short;",
+ new Generator().valueOf(Type.SHORT_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;",
+ new Generator().valueOf(Type.INT_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;",
+ new Generator().valueOf(Type.LONG_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Float.valueOf (F)Ljava/lang/Float;",
+ new Generator().valueOf(Type.FLOAT_TYPE));
+ assertEquals(
+ "INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;",
+ new Generator().valueOf(Type.DOUBLE_TYPE));
+ }
+
+ @Test
+ void testUnbox() {
+ assertEquals("", new Generator().unbox(Type.VOID_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Boolean INVOKEVIRTUAL java/lang/Boolean.booleanValue ()Z",
+ new Generator().unbox(Type.BOOLEAN_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.intValue ()I",
+ new Generator().unbox(Type.BYTE_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Character INVOKEVIRTUAL java/lang/Character.charValue ()C",
+ new Generator().unbox(Type.CHAR_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.intValue ()I",
+ new Generator().unbox(Type.SHORT_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.intValue ()I",
+ new Generator().unbox(Type.INT_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.longValue ()J",
+ new Generator().unbox(Type.LONG_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.floatValue ()F",
+ new Generator().unbox(Type.FLOAT_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number INVOKEVIRTUAL java/lang/Number.doubleValue ()D",
+ new Generator().unbox(Type.DOUBLE_TYPE));
+ assertEquals("", new Generator().unbox(OBJECT_TYPE));
+ assertEquals(
+ "CHECKCAST java/lang/Number",
+ new Generator().unbox(Type.getObjectType("java/lang/Number")));
+ assertEquals("CHECKCAST [I", new Generator().unbox(Type.getType("[I")));
+ }
+
+ @Test
+ void testIfCmp() throws GeneratorException {
+ assertEquals("IF_ICMPEQ L0", new Generator().ifCmp(Type.INT_TYPE, EQ, new Label()));
+ assertEquals("IF_ICMPNE L0", new Generator().ifCmp(Type.INT_TYPE, NE, new Label()));
+ assertEquals("IF_ICMPGE L0", new Generator().ifCmp(Type.INT_TYPE, GE, new Label()));
+ assertEquals("IF_ICMPGT L0", new Generator().ifCmp(Type.INT_TYPE, GT, new Label()));
+ assertEquals("IF_ICMPLE L0", new Generator().ifCmp(Type.INT_TYPE, LE, new Label()));
+ assertEquals("IF_ICMPLT L0", new Generator().ifCmp(Type.INT_TYPE, LT, new Label()));
+ assertEquals("LCMP IFGE L0", new Generator().ifCmp(Type.LONG_TYPE, GE, new Label()));
+ assertEquals("FCMPL IFGE L0", new Generator().ifCmp(Type.FLOAT_TYPE, GE, new Label()));
+ assertEquals("FCMPL IFGT L0", new Generator().ifCmp(Type.FLOAT_TYPE, GT, new Label()));
+ assertEquals("FCMPG IFLE L0", new Generator().ifCmp(Type.FLOAT_TYPE, LE, new Label()));
+ assertEquals("FCMPG IFLT L0", new Generator().ifCmp(Type.FLOAT_TYPE, LT, new Label()));
+ assertEquals("DCMPL IFGE L0", new Generator().ifCmp(Type.DOUBLE_TYPE, GE, new Label()));
+ assertEquals("DCMPL IFGT L0", new Generator().ifCmp(Type.DOUBLE_TYPE, GT, new Label()));
+ assertEquals("DCMPG IFLE L0", new Generator().ifCmp(Type.DOUBLE_TYPE, LE, new Label()));
+ assertEquals("DCMPG IFLT L0", new Generator().ifCmp(Type.DOUBLE_TYPE, LT, new Label()));
+ assertEquals("IF_ACMPEQ L0", new Generator().ifCmp(OBJECT_TYPE, EQ, new Label()));
+ assertEquals("IF_ACMPNE L0", new Generator().ifCmp(OBJECT_TYPE, NE, new Label()));
+ assertEquals("IF_ACMPEQ L0", new Generator().ifCmp(Type.getType("[I"), EQ, new Label()));
+ assertEquals("IF_ACMPNE L0", new Generator().ifCmp(Type.getType("[I"), NE, new Label()));
+ assertThrows(
+ GeneratorException.class, () -> new Generator().ifCmp(OBJECT_TYPE, GE, new Label()));
+ assertThrows(
+ GeneratorException.class, () -> new Generator().ifCmp(Type.getType("[I"), GE, new Label()));
+ assertThrows(
+ GeneratorException.class, () -> new Generator().ifCmp(Type.INT_TYPE, 0, new Label()));
+ }
+
+ @Test
+ void testMark() {
+ assertEquals("L0", new Generator().mark(new Label()));
+ }
+
+ @Test
+ void testIfICmp() throws GeneratorException {
+ assertEquals("IF_ICMPEQ L0", new Generator().ifICmp(EQ, new Label()));
+ assertEquals("IF_ICMPNE L0", new Generator().ifICmp(NE, new Label()));
+ assertEquals("IF_ICMPGE L0", new Generator().ifICmp(GE, new Label()));
+ assertEquals("IF_ICMPGT L0", new Generator().ifICmp(GT, new Label()));
+ assertEquals("IF_ICMPLE L0", new Generator().ifICmp(LE, new Label()));
+ assertEquals("IF_ICMPLT L0", new Generator().ifICmp(LT, new Label()));
+ assertThrows(GeneratorException.class, () -> new Generator().ifICmp(0, new Label()));
+ }
+
+ @Test
+ void testIfZCmp() {
+ assertEquals("IFEQ L0", new Generator().ifZCmp(EQ, new Label()));
+ assertEquals("IFNE L0", new Generator().ifZCmp(NE, new Label()));
+ assertEquals("IFGE L0", new Generator().ifZCmp(GE, new Label()));
+ assertEquals("IFGT L0", new Generator().ifZCmp(GT, new Label()));
+ assertEquals("IFLE L0", new Generator().ifZCmp(LE, new Label()));
+ assertEquals("IFLT L0", new Generator().ifZCmp(LT, new Label()));
+ }
+
+ @Test
+ void testIfNull() {
+ assertEquals("IFNULL L0", new Generator().ifNull(new Label()));
+ }
+
+ @Test
+ void testIfNonNull() {
+ assertEquals("IFNONNULL L0", new Generator().ifNonNull(new Label()));
+ }
+
+ @Test
+ void testGoto() {
+ Generator generator = new Generator();
+ Label label = generator.newLabel();
+
+ String goTo = generator.goTo(label);
+
+ assertEquals("GOTO L0", goTo);
+ }
+
+ @Test
+ void testTableSwitch() throws GeneratorException {
+ assertEquals("L0 ICONST_M1 L1", new Generator().tableSwitch(new int[0]));
+ assertEquals(
+ "TABLESWITCH\n"
+ + " 0: L0\n"
+ + " 1: L1\n"
+ + " default: L2 L0 ICONST_0 L1 ICONST_1 L2 ICONST_M1 L3",
+ new Generator().tableSwitch(new int[] {0, 1}));
+ assertEquals(
+ "LOOKUPSWITCH\n"
+ + " 0: L0\n"
+ + " 1: L1\n"
+ + " default: L2 L0 ICONST_0 L1 ICONST_1 L2 ICONST_M1 L3",
+ new Generator().tableSwitch(new int[] {0, 1}, false));
+ assertEquals(
+ "LOOKUPSWITCH\n"
+ + " 0: L0\n"
+ + " 4: L1\n"
+ + " default: L2 L0 ICONST_0 L1 ICONST_4 L2 ICONST_M1 L3",
+ new Generator().tableSwitch(new int[] {0, 4}));
+ assertEquals(
+ "TABLESWITCH\n"
+ + " 0: L0\n"
+ + " 1: L1\n"
+ + " 2: L1\n"
+ + " 3: L1\n"
+ + " 4: L2\n"
+ + " default: L1 L0 ICONST_0 L2 ICONST_4 L1 ICONST_M1 L3",
+ new Generator().tableSwitch(new int[] {0, 4}, true));
+ assertThrows(GeneratorException.class, () -> new Generator().tableSwitch(new int[] {1, 0}));
+ }
+
+ @Test
+ void testRet() {
+ assertEquals("RET 5", new Generator().ret(5));
+ }
+
+ @Test
+ void testReturnValue() {
+ assertEquals("RETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()V").returnValue());
+ assertEquals("IRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()Z").returnValue());
+ assertEquals("IRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()B").returnValue());
+ assertEquals("IRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()C").returnValue());
+ assertEquals("IRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()S").returnValue());
+ assertEquals("IRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()I").returnValue());
+ assertEquals("LRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()J").returnValue());
+ assertEquals("FRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()F").returnValue());
+ assertEquals("DRETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()D").returnValue());
+ assertEquals("ARETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()[I").returnValue());
+ assertEquals("ARETURN", new Generator(Opcodes.ACC_PUBLIC, "m", "()Lpkg/Class").returnValue());
+ }
+
+ @Test
+ void testGetStatic() {
+ assertEquals(
+ "GETSTATIC pkg/Class.f : I",
+ new Generator().getStatic(Type.getObjectType("pkg/Class"), "f", Type.INT_TYPE));
+ }
+
+ @Test
+ void testPutStatic() {
+ assertEquals(
+ "PUTSTATIC pkg/Class.f : I",
+ new Generator().putStatic(Type.getObjectType("pkg/Class"), "f", Type.INT_TYPE));
+ }
+
+ @Test
+ void testGetField() {
+ assertEquals(
+ "GETFIELD pkg/Class.f : I",
+ new Generator().getField(Type.getObjectType("pkg/Class"), "f", Type.INT_TYPE));
+ }
+
+ @Test
+ void testPutField() {
+ assertEquals(
+ "PUTFIELD pkg/Class.f : I",
+ new Generator().putField(Type.getObjectType("pkg/Class"), "f", Type.INT_TYPE));
+ }
+
+ @Test
+ void testInvokeVirtual() {
+ assertEquals(
+ "INVOKEVIRTUAL pkg/Class.m (I)J",
+ new Generator().invokeVirtual(Type.getObjectType("pkg/Class"), new Method("m", "(I)J")));
+ }
+
+ @Test
+ void testInvokeConstructor() {
+ assertEquals(
+ "INVOKESPECIAL pkg/Class.<init> (I)J",
+ new Generator()
+ .invokeConstructor(Type.getObjectType("pkg/Class"), new Method("<init>", "(I)J")));
+ }
+
+ @Test
+ void testInvokeStatic() {
+ assertEquals(
+ "INVOKESTATIC pkg/Class.m (I)J",
+ new Generator().invokeStatic(Type.getObjectType("pkg/Class"), new Method("m", "(I)J")));
+ }
+
+ @Test
+ void testInvokeInterface() {
+ assertEquals(
+ "INVOKEINTERFACE pkg/Class.m (I)J (itf)",
+ new Generator().invokeInterface(Type.getObjectType("pkg/Class"), new Method("m", "(I)J")));
+ }
+
+ @Test
+ void testInvokeDynamic() {
+ assertEquals(
+ "INVOKEDYNAMIC m(I)J [\n"
+ + " // handle kind 0x2 : GETSTATIC\n"
+ + " pkg/Owner.name(I)\n"
+ + " // arguments:\n"
+ + " 1, \n"
+ + " 2, \n"
+ + " 3\n"
+ + " ]",
+ new Generator()
+ .invokeDynamic(
+ "m",
+ "(I)J",
+ new Handle(Opcodes.H_GETSTATIC, "pkg/Owner", "name", "I", false),
+ 1,
+ 2,
+ 3));
+ }
+
+ @Test
+ void testNewInstance() {
+ assertEquals("NEW pkg/Class", new Generator().newInstance(Type.getObjectType("pkg/Class")));
+ }
+
+ @Test
+ void testNewArray() {
+ assertEquals("NEWARRAY T_BOOLEAN", new Generator().newArray(Type.BOOLEAN_TYPE));
+ assertEquals("NEWARRAY T_BYTE", new Generator().newArray(Type.BYTE_TYPE));
+ assertEquals("NEWARRAY T_CHAR", new Generator().newArray(Type.CHAR_TYPE));
+ assertEquals("NEWARRAY T_SHORT", new Generator().newArray(Type.SHORT_TYPE));
+ assertEquals("NEWARRAY T_INT", new Generator().newArray(Type.INT_TYPE));
+ assertEquals("NEWARRAY T_FLOAT", new Generator().newArray(Type.FLOAT_TYPE));
+ assertEquals("NEWARRAY T_LONG", new Generator().newArray(Type.LONG_TYPE));
+ assertEquals("NEWARRAY T_DOUBLE", new Generator().newArray(Type.DOUBLE_TYPE));
+ assertEquals("ANEWARRAY pkg/Class", new Generator().newArray(Type.getObjectType("pkg/Class")));
+ assertEquals("ANEWARRAY [I", new Generator().newArray(Type.getType("[I")));
+ }
+
+ @Test
+ void testArrayLength() {
+ assertEquals("ARRAYLENGTH", new Generator().arrayLength());
+ }
+
+ @Test
+ void testThrowException() {
+ assertEquals("ATHROW", new Generator().throwException());
+ assertEquals(
+ "NEW pkg/Exception DUP LDC \"msg\" "
+ + "INVOKESPECIAL pkg/Exception.<init> (Ljava/lang/String;)V ATHROW",
+ new Generator().throwException(Type.getObjectType("pkg/Exception"), "msg"));
+ }
+
+ @Test
+ void testCheckcast() {
+ assertEquals("", new Generator().checkCast(OBJECT_TYPE));
+ assertEquals("CHECKCAST pkg/Class", new Generator().checkCast(Type.getObjectType("pkg/Class")));
+ }
+
+ @Test
+ void testInstanceOf() {
+ assertEquals("INSTANCEOF pkg/Class", new Generator().instanceOf(Type.getType("Lpkg/Class;")));
+ }
+
+ @Test
+ void testMonitorEnter() {
+ assertEquals("MONITORENTER", new Generator().monitorEnter());
+ }
+
+ @Test
+ void testMonitorExit() {
+ assertEquals("MONITOREXIT", new Generator().monitorExit());
+ }
+
+ @Test
+ void testEndMethod() {
+ assertEquals("MAXSTACK = 0 MAXLOCALS = 0", new Generator().endMethod());
+ assertEquals("", new Generator(Opcodes.ACC_ABSTRACT, "m", "()V").endMethod());
+ }
+
+ @Test
+ void testCatchException() {
+ assertEquals(
+ "TRYCATCHBLOCK L0 L1 L2 null L2",
+ new Generator().catchException(new Label(), new Label(), null));
+ assertEquals(
+ "TRYCATCHBLOCK L0 L1 L2 pkg/Exception L2",
+ new Generator()
+ .catchException(new Label(), new Label(), Type.getObjectType("pkg/Exception")));
+ }
+
+ private static class GeneratorException extends Exception {
+
+ private static final long serialVersionUID = -7167830120642305483L;
+
+ public GeneratorException(final Throwable cause) {
+ super(cause);
+ }
+ }
+
+ private static class Generator implements TableSwitchGenerator {
+
+ private final Textifier textifier;
+ private final GeneratorAdapter generatorAdapter;
+
+ Generator() {
+ this(Opcodes.ACC_PUBLIC, "m", "()V");
+ }
+
+ Generator(final int access, final String name, final String descriptor) {
+ textifier = new Textifier();
+ generatorAdapter =
+ new GeneratorAdapter(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL,
+ new TraceMethodVisitor(textifier),
+ access,
+ name,
+ descriptor) {};
+ }
+
+ public String push(final boolean value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final int value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final long value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final float value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final double value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final String value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final Type value) {
+ generatorAdapter.push(value);
+ return toString();
+ }
+
+ public String push(final Handle handle) {
+ generatorAdapter.push(handle);
+ return toString();
+ }
+
+ public String loadThis() {
+ generatorAdapter.loadThis();
+ return toString();
+ }
+
+ public String loadArg(final int arg) {
+ generatorAdapter.loadArg(arg);
+ return toString();
+ }
+
+ public String loadArgs(final int arg, final int count) {
+ generatorAdapter.loadArgs(arg, count);
+ return toString();
+ }
+
+ public String loadArgs() {
+ generatorAdapter.loadArgs();
+ return toString();
+ }
+
+ public String loadArgArray() {
+ generatorAdapter.loadArgArray();
+ return toString();
+ }
+
+ public String storeArg(final int arg) {
+ generatorAdapter.storeArg(arg);
+ return toString();
+ }
+
+ public int newLocal(final Type type) {
+ return generatorAdapter.newLocal(type);
+ }
+
+ public Type getLocalType(final int local) {
+ return generatorAdapter.getLocalType(local);
+ }
+
+ public String loadLocal(final int local) {
+ generatorAdapter.loadLocal(local);
+ return toString();
+ }
+
+ public String loadLocal(final int local, final Type type) {
+ generatorAdapter.loadLocal(local, type);
+ return toString();
+ }
+
+ public String storeLocal(final int local) {
+ generatorAdapter.storeLocal(local);
+ return toString();
+ }
+
+ public String storeLocal(final int local, final Type type) {
+ generatorAdapter.storeLocal(local, type);
+ return toString();
+ }
+
+ public String arrayLoad(final Type type) {
+ generatorAdapter.arrayLoad(type);
+ return toString();
+ }
+
+ public String arrayStore(final Type type) {
+ generatorAdapter.arrayStore(type);
+ return toString();
+ }
+
+ public String pop() {
+ generatorAdapter.pop();
+ return toString();
+ }
+
+ public String pop2() {
+ generatorAdapter.pop2();
+ return toString();
+ }
+
+ public String dup() {
+ generatorAdapter.dup();
+ return toString();
+ }
+
+ public String dup2() {
+ generatorAdapter.dup2();
+ return toString();
+ }
+
+ public String dupX1() {
+ generatorAdapter.dupX1();
+ return toString();
+ }
+
+ public String dupX2() {
+ generatorAdapter.dupX2();
+ return toString();
+ }
+
+ public String dup2X1() {
+ generatorAdapter.dup2X1();
+ return toString();
+ }
+
+ public String dup2X2() {
+ generatorAdapter.dup2X2();
+ return toString();
+ }
+
+ public String swap() {
+ generatorAdapter.swap();
+ return toString();
+ }
+
+ public String swap(final Type prev, final Type type) {
+ generatorAdapter.swap(prev, type);
+ return toString();
+ }
+
+ public String math(final int op, final Type type) {
+ generatorAdapter.math(op, type);
+ return toString();
+ }
+
+ public String not() {
+ generatorAdapter.not();
+ return toString();
+ }
+
+ public String iinc(final int local, final int amount) {
+ generatorAdapter.iinc(local, amount);
+ return toString();
+ }
+
+ public String cast(final Type from, final Type to) {
+ generatorAdapter.cast(from, to);
+ return toString();
+ }
+
+ public String box(final Type type) {
+ generatorAdapter.box(type);
+ return toString();
+ }
+
+ public String valueOf(final Type type) {
+ generatorAdapter.valueOf(type);
+ return toString();
+ }
+
+ public String unbox(final Type type) {
+ generatorAdapter.unbox(type);
+ return toString();
+ }
+
+ public Label newLabel() {
+ return generatorAdapter.newLabel();
+ }
+
+ public String mark(final Label label) {
+ generatorAdapter.mark(label);
+ return toString();
+ }
+
+ public String ifCmp(final Type type, final int mode, final Label label)
+ throws GeneratorException {
+ try {
+ generatorAdapter.ifCmp(type, mode, label);
+ } catch (IllegalArgumentException e) {
+ throw new GeneratorException(e);
+ }
+ return toString();
+ }
+
+ public String ifICmp(final int mode, final Label label) throws GeneratorException {
+ try {
+ generatorAdapter.ifICmp(mode, label);
+ } catch (IllegalArgumentException e) {
+ throw new GeneratorException(e);
+ }
+ return toString();
+ }
+
+ public String ifZCmp(final int mode, final Label label) {
+ generatorAdapter.ifZCmp(mode, label);
+ return toString();
+ }
+
+ public String ifNull(final Label label) {
+ generatorAdapter.ifNull(label);
+ return toString();
+ }
+
+ public String ifNonNull(final Label label) {
+ generatorAdapter.ifNonNull(label);
+ return toString();
+ }
+
+ public String goTo(final Label label) {
+ generatorAdapter.goTo(label);
+ return toString();
+ }
+
+ public String ret(final int local) {
+ generatorAdapter.ret(local);
+ return toString();
+ }
+
+ public String tableSwitch(final int[] keys) throws GeneratorException {
+ try {
+ generatorAdapter.tableSwitch(keys, this);
+ } catch (IllegalArgumentException e) {
+ throw new GeneratorException(e);
+ }
+ return toString();
+ }
+
+ public String tableSwitch(final int[] keys, final boolean useTable) throws GeneratorException {
+ try {
+ generatorAdapter.tableSwitch(keys, this, useTable);
+ } catch (IllegalArgumentException e) {
+ throw new GeneratorException(e);
+ }
+ return toString();
+ }
+
+ @Override
+ public void generateCase(final int key, final Label end) {
+ generatorAdapter.push(key);
+ }
+
+ @Override
+ public void generateDefault() {
+ generatorAdapter.push(-1);
+ }
+
+ public String returnValue() {
+ generatorAdapter.returnValue();
+ return toString();
+ }
+
+ public String getStatic(final Type owner, final String name, final Type type) {
+ generatorAdapter.getStatic(owner, name, type);
+ return toString();
+ }
+
+ public String putStatic(final Type owner, final String name, final Type type) {
+ generatorAdapter.putStatic(owner, name, type);
+ return toString();
+ }
+
+ public String getField(final Type owner, final String name, final Type type) {
+ generatorAdapter.getField(owner, name, type);
+ return toString();
+ }
+
+ public String putField(final Type owner, final String name, final Type type) {
+ generatorAdapter.putField(owner, name, type);
+ return toString();
+ }
+
+ public String invokeVirtual(final Type owner, final Method method) {
+ generatorAdapter.invokeVirtual(owner, method);
+ return toString();
+ }
+
+ public String invokeConstructor(final Type type, final Method method) {
+ generatorAdapter.invokeConstructor(type, method);
+ return toString();
+ }
+
+ public String invokeStatic(final Type owner, final Method method) {
+ generatorAdapter.invokeStatic(owner, method);
+ return toString();
+ }
+
+ public String invokeInterface(final Type owner, final Method method) {
+ generatorAdapter.invokeInterface(owner, method);
+ return toString();
+ }
+
+ public String invokeDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ generatorAdapter.invokeDynamic(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ return toString();
+ }
+
+ public String newInstance(final Type type) {
+ generatorAdapter.newInstance(type);
+ return toString();
+ }
+
+ public String newArray(final Type type) {
+ generatorAdapter.newArray(type);
+ return toString();
+ }
+
+ public String arrayLength() {
+ generatorAdapter.arrayLength();
+ return toString();
+ }
+
+ public String throwException() {
+ generatorAdapter.throwException();
+ return toString();
+ }
+
+ public String throwException(final Type type, final String msg) {
+ generatorAdapter.throwException(type, msg);
+ return toString();
+ }
+
+ public String checkCast(final Type type) {
+ generatorAdapter.checkCast(type);
+ return toString();
+ }
+
+ public String instanceOf(final Type type) {
+ generatorAdapter.instanceOf(type);
+ return toString();
+ }
+
+ public String monitorEnter() {
+ generatorAdapter.monitorEnter();
+ return toString();
+ }
+
+ public String monitorExit() {
+ generatorAdapter.monitorExit();
+ return toString();
+ }
+
+ public String endMethod() {
+ generatorAdapter.endMethod();
+ return toString();
+ }
+
+ public String catchException(final Label start, final Label end, final Type exception) {
+ generatorAdapter.catchException(start, end, exception);
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ String result =
+ textifier.text.stream()
+ .map(text -> text.toString().trim())
+ .collect(Collectors.joining(" "));
+ textifier.text.clear();
+ return result;
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java
new file mode 100644
index 00000000..65476eef
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java
@@ -0,0 +1,299 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.objectweb.asm.commons.MethodNodeBuilder.toText;
+
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.util.Textifier;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
+/**
+ * Unit tests for {@link InstructionAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class InstructionAdapterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ MethodNode methodNode = new MethodNode();
+
+ assertDoesNotThrow(() -> new InstructionAdapter(methodNode));
+ assertThrows(IllegalStateException.class, () -> new InstructionAdapter(methodNode) {});
+ }
+
+ @Test
+ void testVisitInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitInsn = () -> instructionAdapter.visitInsn(Opcodes.GOTO);
+
+ assertThrows(IllegalArgumentException.class, visitInsn);
+ }
+
+ @Test
+ void testVisitIntInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitIntInsn = () -> instructionAdapter.visitIntInsn(Opcodes.GOTO, 0);
+
+ assertThrows(IllegalArgumentException.class, visitIntInsn);
+ }
+
+ @Test
+ void testVisitIntInsn_illegalNewArrayArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitIntInsn = () -> instructionAdapter.visitIntInsn(Opcodes.NEWARRAY, 0);
+
+ assertThrows(IllegalArgumentException.class, visitIntInsn);
+ }
+
+ @Test
+ void testVisitVarInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitVarInsn = () -> instructionAdapter.visitVarInsn(Opcodes.GOTO, 0);
+
+ assertThrows(IllegalArgumentException.class, visitVarInsn);
+ }
+
+ @Test
+ void testVisitTypeInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitTypeInsn = () -> instructionAdapter.visitTypeInsn(Opcodes.GOTO, "pkg/Class");
+
+ assertThrows(IllegalArgumentException.class, visitTypeInsn);
+ }
+
+ @Test
+ void testVisitFieldInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitFieldInsn =
+ () -> instructionAdapter.visitFieldInsn(Opcodes.INVOKEVIRTUAL, "pkg/Class", "name", "I");
+
+ assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitMethodInsn =
+ () -> instructionAdapter.visitMethodInsn(Opcodes.GETFIELD, "pkg/Class", "name", "I");
+
+ assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ }
+
+ @Test
+ void testVisitMethodInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitMethodInsn =
+ () -> instructionAdapter.visitMethodInsn(Opcodes.GETFIELD, "pkg/Class", "name", "I", false);
+
+ assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ }
+
+ @Test
+ void testVisitJumpInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitJumpInsn = () -> instructionAdapter.visitJumpInsn(Opcodes.NOP, new Label());
+
+ assertThrows(IllegalArgumentException.class, visitJumpInsn);
+ }
+
+ @Test
+ void testVisitLdcInsn() {
+ Textifier textifier = new Textifier();
+ InstructionAdapter instructionAdapter =
+ new InstructionAdapter(new TraceMethodVisitor(textifier));
+
+ instructionAdapter.visitLdcInsn(Boolean.FALSE);
+ instructionAdapter.visitLdcInsn(Boolean.TRUE);
+ instructionAdapter.visitLdcInsn(Byte.valueOf((byte) 2));
+ instructionAdapter.visitLdcInsn(Character.valueOf('3'));
+ instructionAdapter.visitLdcInsn(Short.valueOf((short) 4));
+ instructionAdapter.visitLdcInsn(Integer.valueOf(5));
+ instructionAdapter.visitLdcInsn(Long.valueOf(6));
+ instructionAdapter.visitLdcInsn(Float.valueOf(7.0f));
+ instructionAdapter.visitLdcInsn(Double.valueOf(8.0));
+ instructionAdapter.visitLdcInsn("9");
+ instructionAdapter.visitLdcInsn(Type.getObjectType("pkg/Class"));
+ instructionAdapter.visitLdcInsn(
+ new Handle(Opcodes.H_GETFIELD, "pkg/Class", "name", "I", /* isInterface= */ false));
+
+ assertEquals(
+ "ICONST_0 ICONST_1 ICONST_2 BIPUSH 51 ICONST_4 ICONST_5 LDC 6 LDC 7.0 LDC 8.0 LDC \"9\" "
+ + "LDC Lpkg/Class;.class LDC pkg/Class.nameI (1)",
+ textifier.text.stream()
+ .map(text -> text.toString().trim())
+ .collect(Collectors.joining(" ")));
+ }
+
+ @Test
+ void testVisitLdcInsn_illegalArgument() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(new MethodNode());
+
+ Executable visitLdcInsn = () -> instructionAdapter.visitLdcInsn(new Object());
+
+ assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedInvokeSpecial() {
+ MethodNode methodNode = new MethodNode();
+ InstructionAdapter instructionAdapter = new InstructionAdapter(methodNode);
+
+ instructionAdapter.invokespecial("pkg/Class", "name", "()V");
+
+ assertTrue(toText(methodNode).trim().startsWith("INVOKESPECIAL pkg/Class.name ()V"));
+ }
+
+ @Test
+ void testInvokeSpecial_unsupportedOperation() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(Opcodes.ASM4, null);
+
+ Executable invokeSpecial =
+ () -> instructionAdapter.invokespecial("pkg/Class", "name", "()V", /* isInterface= */ true);
+
+ assertThrows(UnsupportedOperationException.class, invokeSpecial);
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedInvokeVirtual() {
+ MethodNode methodNode = new MethodNode();
+ InstructionAdapter instructionAdapter = new InstructionAdapter(methodNode);
+
+ instructionAdapter.invokevirtual("pkg/Class", "name", "()V");
+
+ assertTrue(toText(methodNode).trim().startsWith("INVOKEVIRTUAL pkg/Class.name ()V"));
+ }
+
+ @Test
+ void testInvokeVirtual_unsupportedOperation() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(Opcodes.ASM4, null);
+
+ Executable invokeVirtual =
+ () -> instructionAdapter.invokevirtual("pkg/Class", "name", "()V", /* isInterface= */ true);
+
+ assertThrows(UnsupportedOperationException.class, invokeVirtual);
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedInvokeStatic() {
+ MethodNode methodNode = new MethodNode();
+ InstructionAdapter instructionAdapter = new InstructionAdapter(methodNode);
+
+ instructionAdapter.invokestatic("pkg/Class", "name", "()V");
+
+ assertTrue(toText(methodNode).trim().startsWith("INVOKESTATIC pkg/Class.name ()V"));
+ }
+
+ @Test
+ void testInvokeStatic_unsupportedOperation() {
+ InstructionAdapter instructionAdapter = new InstructionAdapter(Opcodes.ASM4, null);
+
+ Executable invokeStatic =
+ () -> instructionAdapter.invokestatic("pkg/Class", "name", "()V", /* isInterface= */ true);
+
+ assertThrows(UnsupportedOperationException.class, invokeStatic);
+ }
+
+ /** Tests that classes transformed with an InstructionAdapter are unchanged. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor instructionClassAdapter =
+ new InstructionClassAdapter(apiParameter.value(), classWriter);
+
+ Executable accept = () -> classReader.accept(instructionClassAdapter, attributes(), 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(RuntimeException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+ }
+
+ private static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ static class InstructionClassAdapter extends ClassVisitor {
+
+ InstructionClassAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new InstructionAdapter(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {};
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/JsrInlinerAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/JsrInlinerAdapterTest.java
new file mode 100644
index 00000000..a96eff5e
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/JsrInlinerAdapterTest.java
@@ -0,0 +1,1539 @@
+// ASM: a very sm14all and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.objectweb.asm.commons.MethodNodeBuilder.buildClassWithMethod;
+import static org.objectweb.asm.commons.MethodNodeBuilder.toText;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link JSRInlinerAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class JsrInlinerAdapterTest extends AsmTest {
+
+ // Some local variable numbers used in tests.
+ private static final int LOCAL1 = 1;
+ private static final int LOCAL2 = 2;
+ private static final int LOCAL3 = 3;
+ private static final int LOCAL4 = 4;
+ private static final int LOCAL5 = 5;
+
+ // Labels used to generate test cases.
+ private final Label label0 = new Label();
+ private final Label label1 = new Label();
+ private final Label label2 = new Label();
+ private final Label label3 = new Label();
+ private final Label label4 = new Label();
+ private final Label label5 = new Label();
+ private final Label label6 = new Label();
+ private final Label label7 = new Label();
+ private final Label label8 = new Label();
+ private final Label label9 = new Label();
+ private final Label label10 = new Label();
+ private final Label label11 = new Label();
+ private final Label label12 = new Label();
+
+ // Labels used to generate expected results.
+ private final Label expectedLabel0 = new Label();
+ private final Label expectedLabel1 = new Label();
+ private final Label expectedLabel2 = new Label();
+ private final Label expectedLabel3 = new Label();
+ private final Label expectedLabel4 = new Label();
+ private final Label expectedLabel5 = new Label();
+ private final Label expectedLabel6 = new Label();
+ private final Label expectedLabel7 = new Label();
+ private final Label expectedLabel8 = new Label();
+ private final Label expectedLabel9 = new Label();
+ private final Label expectedLabel10 = new Label();
+ private final Label expectedLabel11 = new Label();
+ private final Label expectedLabel12 = new Label();
+ private final Label expectedLabel13 = new Label();
+ private final Label expectedLabel14 = new Label();
+ private final Label expectedLabel15 = new Label();
+ private final Label expectedLabel16 = new Label();
+ private final Label expectedLabel17 = new Label();
+ private final Label expectedLabel18 = new Label();
+ private final Label expectedLabel19 = new Label();
+ private final Label expectedLabel20 = new Label();
+ private final Label expectedLabel21 = new Label();
+ private final Label expectedLabel22 = new Label();
+ private final Label expectedLabel23 = new Label();
+ private final Label expectedLabel24 = new Label();
+ private final Label expectedLabel25 = new Label();
+ private final Label expectedLabel26 = new Label();
+ private final Label expectedLabel27 = new Label();
+ private final Label expectedLabel28 = new Label();
+
+ @Test
+ void testConstructor() {
+ new JSRInlinerAdapter(null, Opcodes.ACC_PUBLIC, "name", "()V", null, null);
+ assertThrows(
+ IllegalStateException.class,
+ () -> new JSRInlinerAdapter(null, Opcodes.ACC_PUBLIC, "name", "()V", null, null) {});
+ }
+
+ /**
+ * Tests a method which has the most basic <code>try{}finally</code> form imaginable. More
+ * specifically:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * a--;
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_basicTryFinally() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // Body of try block.
+ .iinc(1, 1)
+ .go(label3)
+ .label(label1) // Exception handler.
+ .astore(3)
+ .jsr(label2)
+ .aload(3)
+ .athrow()
+ .label(label2) // Subroutine.
+ .astore(2)
+ .iinc(1, -1)
+ .ret(2)
+ .label(label3) // Non-exceptional exit from try block.
+ .jsr(label2)
+ .label(label4)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label1)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // Try/catch block.
+ .iinc(1, 1)
+ .go(expectedLabel3)
+ .label(expectedLabel1) // Exception handler.
+ .astore(3)
+ .aconst_null()
+ .go(expectedLabel6)
+ .label(expectedLabel2)
+ .aload(3)
+ .athrow()
+ .label(expectedLabel3) // On non-exceptional exit, try block leads here.
+ .aconst_null()
+ .go(expectedLabel7)
+ .label(expectedLabel4)
+ .label(expectedLabel5)
+ .vreturn()
+ .label(expectedLabel6) // First instantiation of subroutine.
+ .astore(2)
+ .iinc(1, -1)
+ .go(expectedLabel2)
+ .label()
+ .label(expectedLabel7) // Second instantiation of subroutine.
+ .astore(2)
+ .iinc(1, -1)
+ .go(expectedLabel4)
+ .label()
+ .trycatch(expectedLabel0, expectedLabel1, expectedLabel1)
+ .trycatch(expectedLabel3, expectedLabel5, expectedLabel1)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> MethodNodeBuilder.buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a method which has an if/else in the finally clause. More specifically:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * if (a == 0) {
+ * a += 2;
+ * } else {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_ifElseInFinally() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // Body of try block.
+ .iinc(1, 1)
+ .go(label5)
+ .label(label1) // Exception handler.
+ .astore(3)
+ .jsr(label2)
+ .aload(3)
+ .athrow()
+ .label(label2) // Subroutine.
+ .astore(2)
+ .iload(1)
+ .ifne(label3)
+ .iinc(1, 2)
+ .go(label4)
+ .label(label3) // Test "a != 0".
+ .iinc(1, 3)
+ .label(label4) // Common exit.
+ .ret(2)
+ .label(label5) // Non-exceptional exit from try block.
+ .jsr(label2)
+ .label(label6) // Used in the TRYCATCH below.
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label5, label6, label1)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // Try/catch block.
+ .iinc(1, 1)
+ .go(expectedLabel3)
+ .label(expectedLabel1) // Exception handler.
+ .astore(3)
+ .aconst_null()
+ .go(expectedLabel6)
+ .label(expectedLabel2)
+ .aload(3)
+ .athrow()
+ .label(expectedLabel3) // On non-exceptional exit, try block leads here.
+ .aconst_null()
+ .go(expectedLabel9)
+ .label(expectedLabel4)
+ .label(expectedLabel5)
+ .vreturn()
+ .label(expectedLabel6) // First instantiation of subroutine.
+ .astore(2)
+ .iload(1)
+ .ifne(expectedLabel7)
+ .iinc(1, 2)
+ .go(expectedLabel8)
+ .label(expectedLabel7) // Test "a != 0".
+ .iinc(1, 3)
+ .label(expectedLabel8) // Common exit.
+ .go(expectedLabel2)
+ .label()
+ .label(expectedLabel9) // Second instantiation of subroutine.
+ .astore(2)
+ .iload(1)
+ .ifne(expectedLabel10)
+ .iinc(1, 2)
+ .go(expectedLabel11)
+ .label(expectedLabel10) // Test "a != 0".
+ .iinc(1, 3)
+ .label(expectedLabel11) // Common exit.
+ .go(expectedLabel4)
+ .label()
+ .trycatch(expectedLabel0, expectedLabel1, expectedLabel1)
+ .trycatch(expectedLabel3, expectedLabel5, expectedLabel1)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a method which has a lookupswitch or tableswitch w/in the finally clause. More
+ * specifically:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * switch (a) {
+ * case 0:
+ * a += 2;
+ * break;
+ * default:
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @ParameterizedTest
+ @ValueSource(strings = {"true", "false"})
+ void testInlineJsr_lookupOrTableSwitchInFinally(final boolean useTableSwitch) {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // Body of try block.
+ .iinc(1, 1)
+ .go(label6)
+ .label(label1) // Exception handler.
+ .astore(3)
+ .jsr(label2)
+ .aload(3)
+ .athrow()
+ .label(label2) // Subroutine.
+ .astore(2)
+ .iload(1)
+ .switchto(label4, 0, label3, useTableSwitch)
+ .label(label3) // First switch case.
+ .iinc(1, 2)
+ .go(label5)
+ .label(label4) // Default switch case.
+ .iinc(1, 3)
+ .label(label5) // Common exit.
+ .ret(2)
+ .label(label6) // Non-exceptional exit from try block.
+ .jsr(label2)
+ .label(label7)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label6, label7, label1)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // Try/catch block.
+ .iinc(1, 1)
+ .go(expectedLabel3)
+ .label(expectedLabel1) // Exception handler.
+ .astore(3)
+ .aconst_null()
+ .go(expectedLabel6)
+ .label(expectedLabel2)
+ .aload(3)
+ .athrow()
+ .label(expectedLabel3) // On non-exceptional exit, try block leads here.
+ .aconst_null()
+ .go(expectedLabel10)
+ .label(expectedLabel4)
+ .label(expectedLabel5)
+ .vreturn()
+ .label(expectedLabel6) // First instantiation of subroutine.
+ .astore(2)
+ .iload(1)
+ .switchto(expectedLabel8, 0, expectedLabel7, useTableSwitch)
+ .label(expectedLabel7) // First switch case.
+ .iinc(1, 2)
+ .go(expectedLabel9)
+ .label(expectedLabel8) // Default switch case.
+ .iinc(1, 3)
+ .label(expectedLabel9) // Common exit.
+ .go(expectedLabel2)
+ .label()
+ .label(expectedLabel10) // Second instantiation of subroutine.
+ .astore(2)
+ .iload(1)
+ .switchto(expectedLabel12, 0, expectedLabel11, useTableSwitch)
+ .label(expectedLabel11) // First switch case.
+ .iinc(1, 2)
+ .go(expectedLabel13)
+ .label(expectedLabel12) // Default switch case.
+ .iinc(1, 3)
+ .label(expectedLabel13) // Common exit.
+ .go(expectedLabel4)
+ .label()
+ .trycatch(expectedLabel0, expectedLabel1, expectedLabel1)
+ .trycatch(expectedLabel3, expectedLabel5, expectedLabel1)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a simple nested finally. More specifically:
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * try {
+ * a += 1;
+ * } finally {
+ * try {
+ * a += 2;
+ * } finally {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_simpleNestedFinally() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(2, 6)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // Body of try block.
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label5)
+ .label(label1) // First exception handler.
+ .jsr(label2)
+ .athrow()
+ .label(label2) // First subroutine.
+ .astore(2)
+ .iinc(1, 2)
+ .jsr(label4)
+ .ret(2)
+ .label(label3) // Second exception handler.
+ .jsr(label4)
+ .athrow()
+ .label(label4) // Second subroutine.
+ .astore(3)
+ .iinc(1, 3)
+ .ret(3)
+ .label(label5) // On normal exit, try block jumps here.
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label2, label3, label3)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(2, 6)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // Body of try block.
+ .iinc(1, 1)
+ .aconst_null()
+ .go(expectedLabel5)
+ .label(expectedLabel1)
+ .go(expectedLabel4)
+ .label(expectedLabel2) // First exception handler.
+ .aconst_null()
+ .go(expectedLabel9)
+ .label(expectedLabel3)
+ .athrow()
+ .label(expectedLabel4) // On normal exit, try block jumps here.
+ .vreturn()
+ .label(expectedLabel5) // First instantiation of first subroutine.
+ .astore(2)
+ .iinc(1, 2)
+ .aconst_null()
+ .go(expectedLabel13)
+ .label(expectedLabel6)
+ .go(expectedLabel1)
+ .label(expectedLabel7)
+ .aconst_null()
+ .go(expectedLabel14)
+ .label(expectedLabel8)
+ .athrow()
+ .label()
+ .label(expectedLabel9) // Second instantiation of first subroutine.
+ .astore(2)
+ .iinc(1, 2)
+ .aconst_null()
+ .go(expectedLabel15)
+ .label(expectedLabel10)
+ .go(expectedLabel3)
+ .label(expectedLabel11)
+ .aconst_null()
+ .go(expectedLabel16)
+ .label(expectedLabel12)
+ .athrow()
+ .label()
+ .label(expectedLabel13) // First instantiation of second subroutine.
+ .astore(3)
+ .iinc(1, 3)
+ .go(expectedLabel6)
+ .label()
+ .label(expectedLabel14) // Second instantiation of second subroutine.
+ .astore(3)
+ .iinc(1, 3)
+ .go(expectedLabel8)
+ .label()
+ .label(expectedLabel15) // Third instantiation of second subroutine.
+ .astore(3)
+ .iinc(1, 3)
+ .go(expectedLabel10)
+ .label()
+ .label(expectedLabel16) // Fourth instantiation of second subroutine.
+ .astore(3)
+ .iinc(1, 3)
+ .go(expectedLabel12)
+ .label()
+ .trycatch(expectedLabel0, expectedLabel2, expectedLabel2)
+ .trycatch(expectedLabel5, expectedLabel7, expectedLabel7)
+ .trycatch(expectedLabel9, expectedLabel11, expectedLabel11)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead.
+ *
+ * <p>We structure this as a try/finally with a break in the finally. Because the while loop is
+ * infinite, it's clear from the byte code that the only path which reaches the RETURN instruction
+ * is through the subroutine.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (true) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_subroutineWithNoRet() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // While loop header/try block.
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label3)
+ .label(label1) // Implicit catch block.
+ .astore(2)
+ .jsr(label2)
+ .aload(2)
+ .athrow()
+ .label(label2) // Subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(label4) // ... note that it does not return!
+ .label(label3) // End of the loop... goes back to the top!
+ .go(label0)
+ .label(label4)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // While loop header/try block.
+ .iinc(1, 1)
+ .aconst_null()
+ .go(expectedLabel5)
+ .label(expectedLabel1)
+ .go(expectedLabel4)
+ .label(expectedLabel2) // Implicit catch block.
+ .astore(2)
+ .aconst_null()
+ .go(expectedLabel7)
+ .label(expectedLabel3)
+ .aload(2)
+ .athrow()
+ .label(expectedLabel4) // End of the loop... goes back to the top!
+ .go(expectedLabel0)
+ .label()
+ .label(expectedLabel5) // First instantiation of subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(expectedLabel6) // ... note that it does not return!
+ .label(expectedLabel6)
+ .vreturn()
+ .label(expectedLabel7) // Second instantiation of subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(expectedLabel8) // ... note that it does not return!
+ .label(expectedLabel8)
+ .vreturn()
+ .trycatch(expectedLabel0, expectedLabel2, expectedLabel2)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead. The code
+ * after the JSR appears to fall through the end of the method, but is in fact unreachable and
+ * therefore valid.
+ *
+ * <pre>
+ * JSR L0
+ * GOTO L1
+ * L0:
+ * ASTORE 0
+ * RETURN
+ * L1:
+ * ACONST_NULL
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_subroutineWithNoRet2() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 1)
+ .jsr(label0)
+ .go(label1)
+ .label(label0)
+ .astore(0)
+ .vreturn()
+ .label(label1)
+ .aconst_null()
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 1)
+ .aconst_null()
+ .go(expectedLabel2)
+ .label(expectedLabel0)
+ .go(expectedLabel1)
+ .label(expectedLabel1)
+ .aconst_null()
+ .label(expectedLabel2) // First instantiation of subroutine.
+ .astore(0)
+ .vreturn()
+ .label()
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but instead exits implicitly by branching
+ * to code which is not part of the subroutine. (Sadly, this is legal)
+ *
+ * <p>We structure this as a try/finally in a loop with a break in the finally. The loop is not
+ * trivially infinite, so the RETURN statement is reachable both from the JSR subroutine and from
+ * the main entry point.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (null == null) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_implicitExit() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // While loop header.
+ .aconst_null()
+ .ifnonnull(label5)
+ .label(label1) // Try block.
+ .iinc(1, 1)
+ .jsr(label3)
+ .go(label4)
+ .label(label2) // Implicit catch block.
+ .astore(2)
+ .jsr(label3)
+ .aload(2)
+ .athrow()
+ .label(label3) // Subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(label5) // ... note that it does not return!
+ .label(label4) // End of the loop... goes back to the top!
+ .go(label1)
+ .label(label5)
+ .vreturn()
+ .trycatch(label1, label2, label2)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // While loop header.
+ .aconst_null()
+ .ifnonnull(expectedLabel6)
+ .label(expectedLabel1) // While loop header/try block.
+ .iinc(1, 1)
+ .aconst_null()
+ .go(expectedLabel7)
+ .label(expectedLabel2)
+ .go(expectedLabel5)
+ .label(expectedLabel3) // Implicit catch block.
+ .astore(2)
+ .aconst_null()
+ .go(expectedLabel8)
+ .label(expectedLabel4)
+ .aload(2)
+ .athrow()
+ .label(expectedLabel5) // End of the loop... goes back to the top!
+ .go(expectedLabel1)
+ .label(expectedLabel6) // Exit, not part of subroutine.
+ // Note that the two subroutine instantiations branch here.
+ .vreturn()
+ .label(expectedLabel7) // First instantiation of subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(expectedLabel6) // ... note that it does not return!
+ .label()
+ .label(expectedLabel8) // Second instantiation of subroutine ...
+ .astore(3)
+ .iinc(1, 2)
+ .go(expectedLabel6) // ... note that it does not return!
+ .label()
+ .trycatch(expectedLabel1, expectedLabel3, expectedLabel3)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine.
+ * Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(boolean b) {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>This example is from the paper, "Subroutine Inlining and Bytecode Abstraction to Simplify
+ * Static and Dynamic Analysis" by Cyrille Artho and Armin Biere.
+ */
+ @Test
+ void testInlineJsr_implicitExitToAnotherSubroutine() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 6)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // First try.
+ .jsr(label2)
+ .vreturn()
+ .label(label1) // Exception handler for first try.
+ .astore(LOCAL2)
+ .jsr(label2)
+ .aload(LOCAL2)
+ .athrow()
+ .label(label2) // First finally handler.
+ .astore(LOCAL4)
+ .go(label6)
+ .label(label3) // Body of while loop, also second try.
+ .jsr(label5)
+ .vreturn()
+ .label(label4) // Exception handler for second try.
+ .astore(LOCAL3)
+ .jsr(label5)
+ .aload(LOCAL3)
+ .athrow()
+ .label(label5) // Second finally handler.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label7)
+ .ret(LOCAL5)
+ .label(label6) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(label3) // Falls through.
+ .label(label7) // Exit from finally block.
+ .ret(LOCAL4)
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label4)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 6)
+ // --- Main Subroutine ---
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // First try.
+ .aconst_null()
+ .go(expectedLabel4)
+ .label(expectedLabel1)
+ .vreturn()
+ .label(expectedLabel2) // Exception handler for first try.
+ .astore(LOCAL2)
+ .aconst_null()
+ .go(expectedLabel11)
+ .label(expectedLabel3)
+ .aload(LOCAL2)
+ .athrow()
+ .label()
+ // --- First instantiation of first subroutine ---
+ .label(expectedLabel4) // First finally handler.
+ .astore(LOCAL4)
+ .go(expectedLabel9)
+ .label(expectedLabel5) // Body of while loop, also second try.
+ .aconst_null()
+ .go(expectedLabel18)
+ .label(expectedLabel6)
+ .vreturn()
+ .label(expectedLabel7) // Exception handler for second try.
+ .astore(LOCAL3)
+ .aconst_null()
+ .go(expectedLabel19)
+ .label(expectedLabel8)
+ .aload(LOCAL3)
+ .athrow()
+ .label(expectedLabel9) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(expectedLabel5) // Falls through.
+ .label(expectedLabel10) // Exit from finally block.
+ .go(expectedLabel1)
+ // --- Second instantiation of first subroutine ---
+ .label(expectedLabel11) // First finally handler.
+ .astore(LOCAL4)
+ .go(expectedLabel16)
+ .label(expectedLabel12) // Body of while loop, also second try.
+ .aconst_null()
+ .go(expectedLabel20)
+ .label(expectedLabel13)
+ .vreturn()
+ .label(expectedLabel14) // Exception handler for second try.
+ .astore(LOCAL3)
+ .aconst_null()
+ .go(expectedLabel21)
+ .label(expectedLabel15)
+ .aload(LOCAL3)
+ .athrow()
+ .label(expectedLabel16) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(expectedLabel12) // Falls through.
+ .label(expectedLabel17) // Exit from finally block.
+ .go(expectedLabel3)
+ // --- Second subroutine's 4 instantiations ---
+ .label(expectedLabel18) // First instantiation.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel10)
+ .go(expectedLabel6)
+ .label()
+ .label(expectedLabel19) // Second instantiation.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel10)
+ .go(expectedLabel8)
+ .label()
+ .label(expectedLabel20) // Third instantiation.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel17)
+ .go(expectedLabel13)
+ .label()
+ .label(expectedLabel21) // Fourth instantiation.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel17)
+ .go(expectedLabel15)
+ .label()
+ .trycatch(expectedLabel0, expectedLabel2, expectedLabel2)
+ .trycatch(expectedLabel5, expectedLabel7, expectedLabel7)
+ .trycatch(expectedLabel12, expectedLabel14, expectedLabel14)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * This tests two subroutines, neither of which exit. Instead, they both branch to a common set of
+ * code which returns from the method. This code is not reachable except through these
+ * subroutines, and since they do not invoke each other, it must be copied into both of them.
+ *
+ * <p>I don't believe this can be represented in Java.
+ */
+ @Test
+ void testInlineJsr_commonCodeWhichMustBeDuplicated() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 2)
+ .iconst_0()
+ .istore(1)
+ // Invoke the two subroutines, each twice.
+ .jsr(label0)
+ .jsr(label0)
+ .jsr(label1)
+ .jsr(label1)
+ .vreturn()
+ .label(label0) // Subroutine 1.
+ .iinc(1, 1)
+ .go(label2) // ... note that it does not return!
+ .label(label1) // Subroutine 2.
+ .iinc(1, 2)
+ .go(label2) // ... note that it does not return!
+ .label(label2) // Common code to both subroutines: exit method.
+ .vreturn()
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 2)
+ .iconst_0()
+ .istore(1)
+ // Invoke the two subroutines, each twice.
+ .aconst_null()
+ .go(expectedLabel4)
+ .label(expectedLabel0)
+ .aconst_null()
+ .go(expectedLabel6)
+ .label(expectedLabel1)
+ .aconst_null()
+ .go(expectedLabel8)
+ .label(expectedLabel2)
+ .aconst_null()
+ .go(expectedLabel10)
+ .label(expectedLabel3)
+ .vreturn()
+ .label()
+ .label(expectedLabel4) // Instantiation 1 of subroutine 1.
+ .iinc(1, 1)
+ .go(expectedLabel5) // ... note that it does not return!
+ .label(expectedLabel5)
+ .vreturn()
+ .label(expectedLabel6) // Instantiation 2 of subroutine 1.
+ .iinc(1, 1)
+ .go(expectedLabel7) // ... note that it does not return!
+ .label(expectedLabel7)
+ .vreturn()
+ .label(expectedLabel8) // Instantiation 1 of subroutine 2.
+ .iinc(1, 2)
+ .go(expectedLabel9) // ...note that it does not return!
+ .label(expectedLabel9)
+ .vreturn()
+ .label(expectedLabel10) // Instantiation 2 of subroutine 2.
+ .iinc(1, 2)
+ .go(expectedLabel11) // ... note that it does not return!
+ .label(expectedLabel11)
+ .vreturn()
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * This tests a simple subroutine where the control flow jumps back and forth between the
+ * subroutine and the caller.
+ *
+ * <p>This would not normally be produced by a java compiler.
+ */
+ @Test
+ void testInlineJsr_interleavedCode() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 3)
+ .iconst_0()
+ .istore(1)
+ // Invoke the subroutine, each twice.
+ .jsr(label0)
+ .go(label1)
+ .label(label0) // Subroutine 1.
+ .astore(2)
+ .iinc(1, 1)
+ .go(label2)
+ .label(label1) // Second part of main subroutine.
+ .iinc(1, 2)
+ .go(label3)
+ .label(label2) // Second part of subroutine 1.
+ .iinc(1, 4)
+ .ret(2)
+ .label(label3) // Third part of main subroutine.
+ .jsr(label0)
+ .vreturn()
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 3)
+ // Main routine.
+ .iconst_0()
+ .istore(1)
+ .aconst_null()
+ .go(expectedLabel4)
+ .label(expectedLabel0)
+ .go(expectedLabel1)
+ .label(expectedLabel1)
+ .iinc(1, 2)
+ .go(expectedLabel2)
+ .label(expectedLabel2)
+ .aconst_null()
+ .go(expectedLabel6)
+ .label(expectedLabel3)
+ .vreturn()
+ .label(expectedLabel4) // Instantiation #1.
+ .astore(2)
+ .iinc(1, 1)
+ .go(expectedLabel5)
+ .label(expectedLabel5)
+ .iinc(1, 4)
+ .go(expectedLabel0)
+ .label()
+ .label(expectedLabel6) // Instantiation #2.
+ .astore(2)
+ .iinc(1, 1)
+ .go(expectedLabel7)
+ .label(expectedLabel7)
+ .iinc(1, 4)
+ .go(expectedLabel3)
+ .label()
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine, and
+ * with a surrounding try/catch thrown in the mix. Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(int b) {
+ * try {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * } catch (Exception e) {
+ * b += 3;
+ * return;
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_implicitExitInTryCatch() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 6)
+ .iconst_0()
+ .istore(1)
+ .label(label0) // Outermost try.
+ .label(label1) // First try.
+ .jsr(label3)
+ .vreturn()
+ .label(label2) // Exception handler for first try.
+ .astore(LOCAL2)
+ .jsr(label3)
+ .aload(LOCAL2)
+ .athrow()
+ .label(label3) // First finally handler.
+ .astore(LOCAL4)
+ .go(label7)
+ .label(label4) // Body of while loop, also second try.
+ .jsr(label6)
+ .vreturn()
+ .label(label5) // Exception handler for second try.
+ .astore(LOCAL3)
+ .jsr(label6)
+ .aload(LOCAL3)
+ .athrow()
+ .label(label6) // Second finally handler.
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label8)
+ .ret(LOCAL5)
+ .label(label7) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(label4) // Falls through.
+ .label(label8) // Exit from finally block.
+ .ret(LOCAL4)
+ .label(label9) // Outermost catch.
+ .iinc(LOCAL1, 3)
+ .vreturn()
+ .trycatch(label1, label2, label2)
+ .trycatch(label4, label5, label5)
+ .trycatch(label0, label9, label9)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 6)
+ // --- Main Subroutine ---
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel0) // Outermost try / first try.
+ .aconst_null()
+ .go(expectedLabel5)
+ .label(expectedLabel1)
+ .vreturn()
+ .label(expectedLabel2) // Exception handler for first try.
+ .astore(LOCAL2)
+ .aconst_null()
+ .go(expectedLabel13)
+ .label(expectedLabel3)
+ .aload(LOCAL2)
+ .athrow()
+ .label(expectedLabel4) // Outermost catch.
+ .iinc(LOCAL1, 3)
+ .vreturn()
+ // --- First instantiation of first subroutine ---
+ .label(expectedLabel5) // First finally handler.
+ .astore(LOCAL4)
+ .go(expectedLabel10)
+ .label(expectedLabel6) // Body of while loop, also second try.
+ .aconst_null()
+ .go(expectedLabel21)
+ .label(expectedLabel7)
+ .vreturn()
+ .label(expectedLabel8) // Exception handler for second try.
+ .astore(LOCAL3)
+ .aconst_null()
+ .go(expectedLabel23)
+ .label(expectedLabel9)
+ .aload(LOCAL3)
+ .athrow()
+ .label(expectedLabel10) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(expectedLabel6) // Falls through.
+ .label(expectedLabel11) // Exit from finally block.
+ .go(expectedLabel1)
+ .label(expectedLabel12)
+ // --- Second instantiation of first subroutine ---
+ .label(expectedLabel13) // First finally handler.
+ .astore(LOCAL4)
+ .go(expectedLabel18)
+ .label(expectedLabel14) // Body of while loop, also second try.
+ .aconst_null()
+ .go(expectedLabel25)
+ .label(expectedLabel15)
+ .vreturn()
+ .label(expectedLabel16) // Exception handler for second try.
+ .astore(LOCAL3)
+ .aconst_null()
+ .go(expectedLabel27)
+ .label(expectedLabel17)
+ .aload(LOCAL3)
+ .athrow()
+ .label(expectedLabel18) // Test for the while loop.
+ .iload(LOCAL1)
+ .ifne(expectedLabel14) // Falls through.
+ .label(expectedLabel19) // Exit from finally block.
+ .go(expectedLabel3)
+ .label(expectedLabel20)
+ // --- Second subroutine's 4 instantiations ---
+ .label(expectedLabel21)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel11)
+ .go(expectedLabel7)
+ .label(expectedLabel22)
+ .label(expectedLabel23)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel11)
+ .go(expectedLabel9)
+ .label(expectedLabel24)
+ .label(expectedLabel25)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel19)
+ .go(expectedLabel15)
+ .label(expectedLabel26)
+ .label(expectedLabel27)
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(expectedLabel19)
+ .go(expectedLabel17)
+ .label(expectedLabel28)
+ // Main subroutine handlers.
+ .trycatch(expectedLabel0, expectedLabel2, expectedLabel2)
+ .trycatch(expectedLabel0, expectedLabel4, expectedLabel4)
+ // First instance of first subroutine try/catch handlers.
+ // Note: reuses handler code from main subroutine.
+ .trycatch(expectedLabel6, expectedLabel8, expectedLabel8)
+ .trycatch(expectedLabel5, expectedLabel12, expectedLabel4)
+ // Second instance of first sub try/catch handlers.
+ .trycatch(expectedLabel14, expectedLabel16, expectedLabel16)
+ .trycatch(expectedLabel13, expectedLabel20, expectedLabel4)
+ // All 4 instances of second subroutine.
+ .trycatch(expectedLabel21, expectedLabel22, expectedLabel4)
+ .trycatch(expectedLabel23, expectedLabel24, expectedLabel4)
+ .trycatch(expectedLabel25, expectedLabel26, expectedLabel4)
+ .trycatch(expectedLabel27, expectedLabel28, expectedLabel4)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests an example coming from distilled down version of
+ * com/sun/corba/ee/impl/protocol/CorbaClientDelegateImpl from GlassFish 2. See issue #317823.
+ */
+ @Test
+ void testInlineJsr_glassFish2CorbaClientDelegateImplExample() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(3, 3)
+ .label(label0)
+ .jsr(label4)
+ .label(label1)
+ .go(label5)
+ .label(label2)
+ .pop()
+ .jsr(label4)
+ .label(label3)
+ .aconst_null()
+ .athrow()
+ .label(label4)
+ .astore(1)
+ .ret(1)
+ .label(label5)
+ .aconst_null()
+ .aconst_null()
+ .aconst_null()
+ .pop()
+ .pop()
+ .pop()
+ .label(label6)
+ .go(label8)
+ .label(label7)
+ .pop()
+ .go(label8)
+ .aconst_null()
+ .athrow()
+ .label(label8)
+ .iconst_0()
+ .ifne(label0)
+ .jsr(label12)
+ .label(label9)
+ .vreturn()
+ .label(label10)
+ .pop()
+ .jsr(label12)
+ .label(label11)
+ .aconst_null()
+ .athrow()
+ .label(label12)
+ .astore(2)
+ .ret(2)
+ .trycatch(label0, label1, label2)
+ .trycatch(label2, label3, label2)
+ .trycatch(label0, label6, label7)
+ .trycatch(label0, label9, label10)
+ .trycatch(label10, label11, label10)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(3, 3)
+ // --- Main Subroutine ---
+ .label(expectedLabel0)
+ .aconst_null()
+ .go(expectedLabel15)
+ .label(expectedLabel1)
+ .label(expectedLabel2)
+ .go(expectedLabel6)
+ .label(expectedLabel3)
+ .pop()
+ .aconst_null()
+ .go(expectedLabel17)
+ .label(expectedLabel4)
+ .label(expectedLabel5)
+ .aconst_null()
+ .athrow()
+ .label(expectedLabel6)
+ .aconst_null()
+ .aconst_null()
+ .aconst_null()
+ .pop()
+ .pop()
+ .pop()
+ .label(expectedLabel7)
+ .go(expectedLabel9)
+ .label(expectedLabel8)
+ .pop()
+ .go(expectedLabel9)
+ // [some dead code skipped here]
+ .label(expectedLabel9)
+ .iconst_0()
+ .ifne(expectedLabel0)
+ .aconst_null()
+ .go(expectedLabel19)
+ .label(expectedLabel10)
+ .label(expectedLabel11)
+ .vreturn()
+ .label(expectedLabel12)
+ .pop()
+ .aconst_null()
+ .go(expectedLabel20)
+ .label(expectedLabel13)
+ .label(expectedLabel14)
+ .aconst_null()
+ .athrow()
+ // --- First instantiation of first subroutine ---
+ .label()
+ .label(expectedLabel15)
+ .astore(1)
+ .go(expectedLabel1)
+ .label(expectedLabel16)
+ // --- Second instantiation of first subroutine ---
+ .label(expectedLabel17)
+ .astore(1)
+ .go(expectedLabel4)
+ .label(expectedLabel18)
+ // --- First instantiation of second subroutine ---
+ .label(expectedLabel19)
+ .astore(2)
+ .go(expectedLabel10)
+ // --- Second instantiation of second subroutine ---
+ .label(expectedLabel20)
+ .astore(2)
+ .go(expectedLabel13)
+ .trycatch(expectedLabel0, expectedLabel2, expectedLabel3)
+ .trycatch(expectedLabel3, expectedLabel5, expectedLabel3)
+ .trycatch(expectedLabel0, expectedLabel7, expectedLabel8)
+ .trycatch(expectedLabel0, expectedLabel11, expectedLabel12)
+ .trycatch(expectedLabel12, expectedLabel14, expectedLabel12)
+ .trycatch(expectedLabel15, expectedLabel16, expectedLabel8)
+ .trycatch(expectedLabel15, expectedLabel16, expectedLabel12)
+ .trycatch(expectedLabel17, expectedLabel18, expectedLabel8)
+ .trycatch(expectedLabel17, expectedLabel18, expectedLabel12)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /**
+ * Tests a method which has line numbers and local variable declarations. More specifically:
+ *
+ * <pre>
+ * public void a() {
+ * 1 int a = 0;
+ * 2 try {
+ * 3 a++;
+ * 4 } finally {
+ * 5 a--;
+ * 6 }
+ * }
+ * LV "a" from 1 to 6
+ * </pre>
+ */
+ @Test
+ void testInlineJsr_basicLineNumberAndLocalVars() {
+ MethodNode inputMethod =
+ new MethodNodeBuilder(1, 4)
+ .label(label0)
+ .line(1, label0)
+ .iconst_0()
+ .istore(1)
+ .label(label1) // Body of try block.
+ .line(3, label1)
+ .iinc(1, 1)
+ .go(label4)
+ .label(label2) // Exception handler.
+ .astore(3)
+ .jsr(label3)
+ .aload(3)
+ .athrow()
+ .label(label3) // Subroutine.
+ .line(5, label3)
+ .astore(2)
+ .iinc(1, -1)
+ .ret(2)
+ .label(label4) // Non-exceptional exit from try block.
+ .jsr(label3)
+ .label(label5)
+ .vreturn()
+ .trycatch(label1, label2, label2)
+ .trycatch(label4, label5, label2)
+ .localvar("a", "I", 1, label0, label5)
+ .build();
+
+ MethodNode inlinedMethod = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ inputMethod.accept(
+ new JSRInlinerAdapter(inlinedMethod, Opcodes.ACC_PUBLIC, "m", "()V", null, null));
+
+ MethodNode expectedMethod =
+ new MethodNodeBuilder(1, 4)
+ .label(expectedLabel0)
+ .line(1, expectedLabel0)
+ .iconst_0()
+ .istore(1)
+ .label(expectedLabel1) // Try/catch block.
+ .line(3, expectedLabel1)
+ .iinc(1, 1)
+ .go(expectedLabel4)
+ .label(expectedLabel2) // Exception handler.
+ .astore(3)
+ .aconst_null()
+ .go(expectedLabel7)
+ .label(expectedLabel3)
+ .aload(3)
+ .athrow()
+ .label(expectedLabel4) // On non-exceptional exit, try block leads here.
+ .aconst_null()
+ .go(expectedLabel9)
+ .label(expectedLabel5)
+ .label(expectedLabel6)
+ .vreturn()
+ .label(expectedLabel7) // First instantiation of subroutine.
+ .line(5, expectedLabel7)
+ .astore(2)
+ .iinc(1, -1)
+ .go(expectedLabel3)
+ .label(expectedLabel8)
+ .label(expectedLabel9) // Second instantiation of subroutine.
+ .line(5, expectedLabel9)
+ .astore(2)
+ .iinc(1, -1)
+ .go(expectedLabel5)
+ .label(expectedLabel10)
+ .trycatch(expectedLabel1, expectedLabel2, expectedLabel2)
+ .trycatch(expectedLabel4, expectedLabel6, expectedLabel2)
+ .localvar("a", "I", 1, expectedLabel0, expectedLabel6)
+ .localvar("a", "I", 1, expectedLabel7, expectedLabel8)
+ .localvar("a", "I", 1, expectedLabel9, expectedLabel10)
+ .build();
+ assertEquals(toText(expectedMethod), toText(inlinedMethod));
+ assertDoesNotThrow(() -> buildClassWithMethod(inlinedMethod).newInstance());
+ }
+
+ /** Tests that classes transformed with JSRInlinerAdapter can be loaded and instantiated. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testInlineJsr_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(new JsrInlinerClassAdapter(apiParameter.value(), classWriter), 0);
+
+ ClassFile classFile = new ClassFile(classWriter.toByteArray());
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, () -> classFile.newInstance());
+ } else {
+ assertDoesNotThrow(() -> classFile.newInstance());
+ }
+ }
+
+ static class JsrInlinerClassAdapter extends ClassVisitor {
+
+ JsrInlinerClassAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ return new JSRInlinerAdapter(
+ api, methodVisitor, access, name, descriptor, signature, exceptions) {};
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java
new file mode 100644
index 00000000..bafcedb7
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java
@@ -0,0 +1,248 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link LocalVariablesSorter}.
+ *
+ * @author Eric Bruneton
+ */
+class LocalVariablesSorterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ MethodNode methodNode = new MethodNode();
+
+ assertDoesNotThrow(() -> new LocalVariablesSorter(Opcodes.ACC_PUBLIC, "()V", methodNode));
+ assertThrows(
+ IllegalStateException.class,
+ () -> new LocalVariablesSorter(Opcodes.ACC_PUBLIC, "()V", methodNode) {});
+ }
+
+ @Test
+ void testVisitFrame_emptyFrame() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_PUBLIC, "()V", new MethodNode());
+
+ Executable visitFrame = () -> localVariablesSorter.visitFrame(Opcodes.F_NEW, 0, null, 0, null);
+
+ assertDoesNotThrow(visitFrame);
+ }
+
+ @Test
+ void testVisitFrame_invalidFrameType() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_PUBLIC, "()V", new MethodNode());
+
+ Executable visitFrame = () -> localVariablesSorter.visitFrame(Opcodes.F_FULL, 0, null, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals(
+ "LocalVariablesSorter only accepts expanded frames (see ClassReader.EXPAND_FRAMES)",
+ exception.getMessage());
+ }
+
+ @Test
+ void testNewLocal_boolean() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.BOOLEAN_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_byte() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.BYTE_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_char() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.CHAR_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_short() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.SHORT_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_int() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.INT_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_float() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.FLOAT_TYPE);
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_long() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.LONG_TYPE);
+ assertEquals(2, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_double() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.DOUBLE_TYPE);
+
+ assertEquals(2, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_object() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.getObjectType("pkg/Class"));
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @Test
+ void testNewLocal_array() {
+ LocalVariablesSorter localVariablesSorter =
+ new LocalVariablesSorter(Opcodes.ACC_STATIC, "()V", new MethodNode());
+
+ localVariablesSorter.newLocal(Type.getType("[I"));
+
+ assertEquals(1, localVariablesSorter.nextLocal);
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor localVariablesSorter =
+ new LocalVariablesSorterClassAdapter(apiParameter.value(), classWriter);
+
+ Executable accept = () -> classReader.accept(localVariablesSorter, ClassReader.EXPAND_FRAMES);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ Executable newInstance = () -> new ClassFile(classWriter.toByteArray()).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+ }
+
+ @Test
+ void testAllMethods_issue317586() throws FileNotFoundException, IOException {
+ ClassReader classReader =
+ new ClassReader(Files.newInputStream(Paths.get("src/test/resources/Issue317586.class")));
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor localVariablesSorter =
+ new LocalVariablesSorterClassAdapter(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classWriter);
+
+ classReader.accept(localVariablesSorter, ClassReader.EXPAND_FRAMES);
+
+ assertDoesNotThrow(() -> new ClassFile(classWriter.toByteArray()).newInstance());
+ }
+
+ static class LocalVariablesSorterClassAdapter extends ClassVisitor {
+
+ LocalVariablesSorterClassAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ return new LocalVariablesSorter(api, access, descriptor, methodVisitor) {};
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/MethodNodeBuilder.java b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodNodeBuilder.java
new file mode 100644
index 00000000..9ef289aa
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodNodeBuilder.java
@@ -0,0 +1,267 @@
+// ASM: a very sm14all and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.util.Textifier;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
+/**
+ * A builder of {@link MethodNode}, to construct test cases for unit tests.
+ *
+ * @author Eric Bruneton
+ */
+final class MethodNodeBuilder {
+
+ private final MethodNode methodNode;
+
+ MethodNodeBuilder(final int maxStack, final int maxLocals) {
+ this("m", "()V", maxStack, maxLocals);
+ }
+
+ MethodNodeBuilder(
+ final String name, final String descriptor, final int maxStack, final int maxLocals) {
+ methodNode = new MethodNode(Opcodes.ACC_PUBLIC, name, descriptor, null, null);
+ methodNode.maxStack = maxStack;
+ methodNode.maxLocals = maxLocals;
+ methodNode.visitCode();
+ }
+
+ MethodNodeBuilder insn(final int opcode) {
+ methodNode.visitInsn(opcode);
+ return this;
+ }
+
+ MethodNodeBuilder intInsn(final int opcode, final int operand) {
+ methodNode.visitIntInsn(opcode, operand);
+ return this;
+ }
+
+ MethodNodeBuilder varInsn(final int opcode, final int operand) {
+ methodNode.visitVarInsn(opcode, operand);
+ return this;
+ }
+
+ MethodNodeBuilder typeInsn(final int opcode, final String operand) {
+ methodNode.visitTypeInsn(opcode, operand);
+ return this;
+ }
+
+ MethodNodeBuilder fieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ methodNode.visitFieldInsn(opcode, owner, name, descriptor);
+ return this;
+ }
+
+ MethodNodeBuilder methodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ methodNode.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ return this;
+ }
+
+ MethodNodeBuilder jumpInsn(final int opcode, final Label label) {
+ methodNode.visitJumpInsn(opcode, label);
+ return this;
+ }
+
+ MethodNodeBuilder ldcInsn(final Object value) {
+ methodNode.visitLdcInsn(value);
+ return this;
+ }
+
+ MethodNodeBuilder iconst_0() {
+ methodNode.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ MethodNodeBuilder pop() {
+ methodNode.visitInsn(Opcodes.POP);
+ return this;
+ }
+
+ MethodNodeBuilder istore(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ISTORE, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder aload(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ALOAD, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder iload(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ILOAD, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder astore(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.ASTORE, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder ret(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.RET, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder athrow() {
+ methodNode.visitInsn(Opcodes.ATHROW);
+ return this;
+ }
+
+ MethodNodeBuilder aconst_null() {
+ methodNode.visitInsn(Opcodes.ACONST_NULL);
+ return this;
+ }
+
+ MethodNodeBuilder vreturn() {
+ methodNode.visitInsn(Opcodes.RETURN);
+ return this;
+ }
+
+ MethodNodeBuilder label() {
+ methodNode.visitLabel(new Label());
+ return this;
+ }
+
+ MethodNodeBuilder label(final Label label) {
+ methodNode.visitLabel(label);
+ return this;
+ }
+
+ MethodNodeBuilder iinc(final int varIndex, final int increment) {
+ methodNode.visitIincInsn(varIndex, increment);
+ return this;
+ }
+
+ MethodNodeBuilder go(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.GOTO, label);
+ return this;
+ }
+
+ MethodNodeBuilder jsr(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.JSR, label);
+ return this;
+ }
+
+ MethodNodeBuilder ifnonnull(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.IFNONNULL, label);
+ return this;
+ }
+
+ MethodNodeBuilder ifne(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.IFNE, label);
+ return this;
+ }
+
+ MethodNodeBuilder switchto(
+ final Label defaultLabel, final int key, final Label target, final boolean useTableSwitch) {
+ if (useTableSwitch) {
+ methodNode.visitTableSwitchInsn(key, key, defaultLabel, new Label[] {target});
+ } else {
+ methodNode.visitLookupSwitchInsn(defaultLabel, new int[] {key}, new Label[] {target});
+ }
+ return this;
+ }
+
+ MethodNodeBuilder switchto(final Label label0, final Label label1, final boolean useTableSwitch) {
+ if (useTableSwitch) {
+ methodNode.visitTableSwitchInsn(0, 1, label0, new Label[] {label0, label1});
+ } else {
+ methodNode.visitLookupSwitchInsn(label0, new int[] {1}, new Label[] {label1});
+ }
+ return this;
+ }
+
+ MethodNodeBuilder multiANewArrayInsn(final String descriptor, final int numDimensions) {
+ methodNode.visitMultiANewArrayInsn(descriptor, numDimensions);
+ return this;
+ }
+
+ MethodNodeBuilder trycatch(final Label start, final Label end, final Label handler) {
+ methodNode.visitTryCatchBlock(start, end, handler, null);
+ return this;
+ }
+
+ MethodNodeBuilder line(final int line, final Label start) {
+ methodNode.visitLineNumber(line, start);
+ return this;
+ }
+
+ MethodNodeBuilder localvar(
+ final String name,
+ final String descriptor,
+ final int index,
+ final Label start,
+ final Label end) {
+ methodNode.visitLocalVariable(name, descriptor, null, start, end, index);
+ return this;
+ }
+
+ MethodNode build() {
+ methodNode.visitEnd();
+ return methodNode;
+ }
+
+ static String toText(final MethodNode methodNode) {
+ Textifier textifier = new Textifier();
+ methodNode.accept(new TraceMethodVisitor(textifier));
+
+ StringBuilder stringBuilder = new StringBuilder();
+ for (Object text : textifier.text) {
+ stringBuilder.append(text);
+ }
+ return stringBuilder.toString();
+ }
+
+ static ClassFile buildClassWithMethod(final MethodNode methodNode) {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ classWriter.visitField(Opcodes.ACC_STATIC, "f", "[[I", null, null);
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ methodNode.accept(classWriter);
+ return new ClassFile(classWriter.toByteArray());
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java
new file mode 100644
index 00000000..a8cc9502
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/MethodTest.java
@@ -0,0 +1,133 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Type;
+
+/**
+ * Unit tests for {@link Method}.
+ *
+ * @author Eric Bruneton
+ */
+class MethodTest {
+
+ @Test
+ void testConstructor_fromDescriptor() {
+ Method method = new Method("name", "(I)J");
+
+ assertEquals("name", method.getName());
+ assertEquals("(I)J", method.getDescriptor());
+ assertEquals(Type.LONG_TYPE, method.getReturnType());
+ assertArrayEquals(new Type[] {Type.INT_TYPE}, method.getArgumentTypes());
+ assertEquals("name(I)J", method.toString());
+ }
+
+ @Test
+ void testConstructor_fromTypes() {
+ Method method = new Method("name", Type.LONG_TYPE, new Type[] {Type.INT_TYPE});
+
+ assertEquals("name", method.getName());
+ assertEquals("(I)J", method.getDescriptor());
+ assertEquals(Type.LONG_TYPE, method.getReturnType());
+ assertArrayEquals(new Type[] {Type.INT_TYPE}, method.getArgumentTypes());
+ assertEquals("name(I)J", method.toString());
+ }
+
+ @Test
+ void testGetMethod_fromMethodObject() throws ReflectiveOperationException {
+ Method method = Method.getMethod(Object.class.getMethod("equals", Object.class));
+
+ assertEquals("equals", method.getName());
+ assertEquals("(Ljava/lang/Object;)Z", method.getDescriptor());
+ }
+
+ @Test
+ void testGetMethod_fromConstructorObject() throws ReflectiveOperationException {
+ Method method = Method.getMethod(Object.class.getConstructor());
+
+ assertEquals("<init>", method.getName());
+ assertEquals("()V", method.getDescriptor());
+ }
+
+ @Test
+ void testGetMethod_fromDescriptor() {
+ Method method =
+ Method.getMethod(
+ "boolean name(byte, char, short, int, float, long, double, pkg.Class, pkg.Class[])");
+
+ assertEquals("name", method.getName());
+ assertEquals("(BCSIFJDLpkg/Class;[Lpkg/Class;)Z", method.getDescriptor());
+ }
+
+ @Test
+ void testGetMethod_fromInvalidDescriptor() {
+ assertThrows(IllegalArgumentException.class, () -> Method.getMethod("name()"));
+ assertThrows(IllegalArgumentException.class, () -> Method.getMethod("void name"));
+ assertThrows(IllegalArgumentException.class, () -> Method.getMethod("void name(]"));
+ }
+
+ @Test
+ void testGetMethod_withDefaultPackage() {
+ Method withoutDefaultPackage =
+ Method.getMethod("void name(Object)", /* defaultPackage= */ false);
+ Method withDefaultPackage = Method.getMethod("void name(Object)", /* defaultPackage= */ true);
+
+ assertEquals("(Ljava/lang/Object;)V", withoutDefaultPackage.getDescriptor());
+ assertEquals("(LObject;)V", withDefaultPackage.getDescriptor());
+ }
+
+ @Test
+ void testEquals() {
+ Method nullMethod = null;
+
+ boolean equalsNull = new Method("name", "()V").equals(nullMethod);
+ boolean equalsMethodWithDifferentName =
+ new Method("name", "()V").equals(new Method("other", "()V"));
+ boolean equalsMethodWithDifferentDescriptor =
+ new Method("name", "()V").equals(new Method("name", "(I)J"));
+ boolean equalsSame = new Method("name", "()V").equals(Method.getMethod("void name()"));
+
+ assertFalse(equalsNull);
+ assertFalse(equalsMethodWithDifferentName);
+ assertFalse(equalsMethodWithDifferentDescriptor);
+ assertTrue(equalsSame);
+ }
+
+ @Test
+ void testHashCode() {
+ assertNotEquals(0, new Method("name", "()V").hashCode());
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java
new file mode 100644
index 00000000..40a45c06
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link ModuleHashesAttribute}.
+ *
+ * @author Eric Bruneton
+ */
+class ModuleHashesAttributeTest {
+
+ private static final byte[] HASH1 = {0x1, 0x2, 0x3};
+ private static final byte[] HASH2 = {0x4, 0x5, 0x6};
+
+ @Test
+ void testWriteAndRead() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visitAttribute(
+ new ModuleHashesAttribute(
+ "algorithm",
+ Arrays.asList(new String[] {"module1", "module2"}),
+ Arrays.asList(new byte[][] {HASH1, HASH2})));
+
+ ModuleHashesAttribute moduleHashesAttribute = new ModuleHashesAttribute();
+ new ClassReader(classWriter.toByteArray())
+ .accept(
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ if (attribute instanceof ModuleHashesAttribute) {
+ moduleHashesAttribute.algorithm = ((ModuleHashesAttribute) attribute).algorithm;
+ moduleHashesAttribute.modules = ((ModuleHashesAttribute) attribute).modules;
+ moduleHashesAttribute.hashes = ((ModuleHashesAttribute) attribute).hashes;
+ }
+ }
+ },
+ new Attribute[] {new ModuleHashesAttribute()},
+ 0);
+
+ assertEquals("algorithm", moduleHashesAttribute.algorithm);
+ assertEquals(2, moduleHashesAttribute.modules.size());
+ assertEquals("module1", moduleHashesAttribute.modules.get(0));
+ assertEquals("module2", moduleHashesAttribute.modules.get(1));
+ assertEquals(2, moduleHashesAttribute.hashes.size());
+ assertArrayEquals(HASH1, moduleHashesAttribute.hashes.get(0));
+ assertArrayEquals(HASH2, moduleHashesAttribute.hashes.get(1));
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java
new file mode 100644
index 00000000..7800255d
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java
@@ -0,0 +1,69 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link ModuleResolutionAttribute}.
+ *
+ * @author Eric Bruneton
+ */
+class ModuleResolutionAttributeTest {
+
+ @Test
+ void testWriteAndRead() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visitAttribute(new ModuleResolutionAttribute(123));
+
+ ModuleResolutionAttribute moduleResolutionAttribute = new ModuleResolutionAttribute();
+ new ClassReader(classWriter.toByteArray())
+ .accept(
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ if (attribute instanceof ModuleResolutionAttribute) {
+ moduleResolutionAttribute.resolution =
+ ((ModuleResolutionAttribute) attribute).resolution;
+ }
+ }
+ },
+ new Attribute[] {new ModuleResolutionAttribute()},
+ 0);
+
+ assertEquals(123, moduleResolutionAttribute.resolution);
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java
new file mode 100644
index 00000000..e3e3cf39
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java
@@ -0,0 +1,68 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link ModuleTargetAttribute}.
+ *
+ * @author Eric Bruneton
+ */
+class ModuleTargetAttributeTest {
+
+ @Test
+ void testWriteAndRead() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visitAttribute(new ModuleTargetAttribute("platform"));
+
+ ModuleTargetAttribute moduleTargetAttribute = new ModuleTargetAttribute();
+ new ClassReader(classWriter.toByteArray())
+ .accept(
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ if (attribute instanceof ModuleTargetAttribute) {
+ moduleTargetAttribute.platform = ((ModuleTargetAttribute) attribute).platform;
+ }
+ }
+ },
+ new Attribute[] {new ModuleTargetAttribute()},
+ 0);
+
+ assertEquals("platform", moduleTargetAttribute.platform);
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java
new file mode 100644
index 00000000..bd046138
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java
@@ -0,0 +1,106 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link SerialVersionUIDAdder}.
+ *
+ * @author Eric Bruneton
+ */
+class SerialVersionUidAdderTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new SerialVersionUIDAdder(null));
+ assertThrows(IllegalStateException.class, () -> new SerialVersionUIDAdder(null) {});
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "SerialVersionClass,4654798559887898126",
+ "SerialVersionAnonymousInnerClass$1,2591057588230880800",
+ "SerialVersionInterface,682190902657822970",
+ "SerialVersionEmptyInterface,-2126445979242430981"
+ })
+ void testAllMethods(final String className, final long expectedSvuid) throws IOException {
+ ClassReader classReader = new ClassReader(className);
+ SerialVersionUIDAdder svuidAdder = new SerialVersionUIDAdder(null);
+
+ classReader.accept(svuidAdder, 0);
+ long svuid = svuidAdder.computeSVUID();
+
+ assertEquals(expectedSvuid, svuid);
+ }
+
+ @Test
+ void testAllMethods_enum() throws IOException {
+ ClassReader classReader = new ClassReader("SerialVersionEnum");
+ ClassWriter classWriter = new ClassWriter(0);
+ SerialVersionUIDAdder svuidAdder = new SerialVersionUIDAdder(classWriter);
+
+ classReader.accept(svuidAdder, 0);
+
+ assertFalse(new ClassFile(classWriter.toByteArray()).toString().contains("serialVersionUID"));
+ }
+
+ /**
+ * Tests that SerialVersionUIDAdder succeeds on all precompiled classes, and that it actually adds
+ * a serialVersionUID field.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAllMethods_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(
+ new SerialVersionUIDAdder(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classWriter) {}, 0);
+
+ if ((classReader.getAccess() & Opcodes.ACC_ENUM) == 0) {
+ assertTrue(new ClassFile(classWriter.toByteArray()).toString().contains("serialVersionUID"));
+ }
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/SimpleRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/SimpleRemapperTest.java
new file mode 100644
index 00000000..edba97c8
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/SimpleRemapperTest.java
@@ -0,0 +1,88 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link SimpleRemapper}.
+ *
+ * @author Eric Bruneton
+ */
+class SimpleRemapperTest {
+
+ @Test
+ void testMapSignature_remapParentOnly_nestedClassExtends() {
+ String inputSignature = "LOuter<Ljava/lang/Object;>.Inner;";
+ Remapper remapper = new SimpleRemapper(Collections.singletonMap("Outer", "RenamedOuter"));
+
+ String remappedSignature = remapper.mapSignature(inputSignature, false);
+
+ assertEquals("LRenamedOuter<Ljava/lang/Object;>.Inner;", remappedSignature);
+ }
+
+ @Test
+ void testMapSignature_remapChildOnly_nestedClassExtends() {
+ String inputSignature = "LOuter<Ljava/lang/Object;>.Inner;";
+ Remapper remapper =
+ new SimpleRemapper(Collections.singletonMap("Outer$Inner", "Outer$RenamedInner"));
+
+ String remappedSignature = remapper.mapSignature(inputSignature, false);
+
+ assertEquals("LOuter<Ljava/lang/Object;>.RenamedInner;", remappedSignature);
+ }
+
+ @Test
+ void testMapSignature_remapChildOnly_nestedClassExtends_identifiersWithDollarSign() {
+ String inputSignature = "LOuter<Ljava/lang/Object;>.Inner$1;";
+ Remapper remapper =
+ new SimpleRemapper(Collections.singletonMap("Outer$Inner$1", "Outer$RenamedInner$1"));
+
+ String remappedSignature = remapper.mapSignature(inputSignature, false);
+
+ assertEquals("LOuter<Ljava/lang/Object;>.RenamedInner$1;", remappedSignature);
+ }
+
+ @Test
+ void testMapSignature_remapBothParentAndChild_nestedClassExtends() {
+ String inputSignature = "LOuter<Ljava/lang/Object;>.Inner;";
+ Map<String, String> mapping = new HashMap<>();
+ mapping.put("Outer", "RenamedOuter");
+ mapping.put("Outer$Inner", "RenamedOuter$RenamedInner");
+ Remapper remapper = new SimpleRemapper(mapping);
+
+ String remappedSignature = remapper.mapSignature(inputSignature, false);
+
+ assertEquals("LRenamedOuter<Ljava/lang/Object;>.RenamedInner;", remappedSignature);
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/StaticInitMergerTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/StaticInitMergerTest.java
new file mode 100644
index 00000000..465cbde4
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/StaticInitMergerTest.java
@@ -0,0 +1,83 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.ClassNode;
+
+/**
+ * Unit tests for {@link StaticInitMerger}.
+ *
+ * @author Eric Bruneton
+ */
+class StaticInitMergerTest {
+
+ @Test
+ void testAllMethods_multipleStaticInitBlocks() throws Exception {
+ ClassNode classNode = newClassWithStaticInitBlocks(5);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ ClassVisitor staticInitMerger = new StaticInitMerger("$clinit$", classWriter);
+
+ classNode.accept(staticInitMerger);
+
+ Object instance = new ClassFile(classWriter.toByteArray()).newInstance();
+ assertEquals(5, instance.getClass().getField("counter").getInt(instance));
+ }
+
+ private static ClassNode newClassWithStaticInitBlocks(final int numStaticInitBlocks) {
+ ClassNode classNode = new ClassNode();
+ classNode.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "A", null, "java/lang/Object", null);
+ classNode.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "counter", "I", null, null);
+ for (int i = 0; i < numStaticInitBlocks; ++i) {
+ MethodVisitor methodVisitor =
+ classNode.visitMethod(Opcodes.ACC_PUBLIC, "<clinit>", "()V", null, null);
+ methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "A", "counter", "I");
+ methodVisitor.visitInsn(Opcodes.ICONST_1);
+ methodVisitor.visitInsn(Opcodes.IADD);
+ methodVisitor.visitFieldInsn(Opcodes.PUTSTATIC, "A", "counter", "I");
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ }
+ MethodVisitor methodVisitor =
+ classNode.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ classNode.visitEnd();
+ return classNode;
+ }
+}
diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/TryCatchBlockSorterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/TryCatchBlockSorterTest.java
new file mode 100644
index 00000000..e66689d0
--- /dev/null
+++ b/asm-commons/src/test/java/org/objectweb/asm/commons/TryCatchBlockSorterTest.java
@@ -0,0 +1,94 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.commons;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link TryCatchBlockSorter}.
+ *
+ * @author Eric Bruneton
+ */
+class TryCatchBlockSorterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(
+ () -> new TryCatchBlockSorter(null, Opcodes.ACC_PUBLIC, "name", "()V", null, null));
+ assertThrows(
+ IllegalStateException.class,
+ () -> new TryCatchBlockSorter(null, Opcodes.ACC_PUBLIC, "name", "()V", null, null) {});
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAllMethods_precompileClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor classVisitor =
+ new ClassVisitor(apiParameter.value(), classWriter) {
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new TryCatchBlockSorter(
+ super.visitMethod(access, name, descriptor, signature, exceptions),
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions);
+ }
+ };
+
+ classReader.accept(classVisitor, 0);
+
+ ClassFile classFile = new ClassFile(classWriter.toByteArray());
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, () -> classFile.newInstance());
+ } else {
+ assertDoesNotThrow(() -> classFile.newInstance());
+ }
+ }
+}
diff --git a/asm-commons/src/test/resources/Issue317586.class b/asm-commons/src/test/resources/Issue317586.class
new file mode 100644
index 00000000..32af483e
--- /dev/null
+++ b/asm-commons/src/test/resources/Issue317586.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass$1.class b/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass$1.class
new file mode 100644
index 00000000..c48cbeca
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass$1.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass.class b/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass.class
new file mode 100644
index 00000000..967abb03
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionAnonymousInnerClass.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionClass.class b/asm-commons/src/test/resources/SerialVersionClass.class
new file mode 100644
index 00000000..54577cd6
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionClass.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionEmptyInterface.class b/asm-commons/src/test/resources/SerialVersionEmptyInterface.class
new file mode 100644
index 00000000..d41cc578
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionEmptyInterface.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionEnum.class b/asm-commons/src/test/resources/SerialVersionEnum.class
new file mode 100644
index 00000000..149c9666
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionEnum.class
Binary files differ
diff --git a/asm-commons/src/test/resources/SerialVersionInterface.class b/asm-commons/src/test/resources/SerialVersionInterface.class
new file mode 100644
index 00000000..164e9d1a
--- /dev/null
+++ b/asm-commons/src/test/resources/SerialVersionInterface.class
Binary files differ
diff --git a/asm-commons/src/test/resources/sigtest-4.0.txt b/asm-commons/src/test/resources/sigtest-4.0.txt
new file mode 100644
index 00000000..bf8b5ca7
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-4.0.txt
@@ -0,0 +1,747 @@
+#Signature file v4.1
+#Version 4.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List locals
+fld public java.util.List stack
+fld public java.util.Map uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds dualCitizens,mainSubroutine,subroutineHeads
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public int newLocal(org.objectweb.asm.Type)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,changed,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List localVariables
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-4.1.txt b/asm-commons/src/test/resources/sigtest-4.1.txt
new file mode 100644
index 00000000..d079d5ce
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-4.1.txt
@@ -0,0 +1,750 @@
+#Signature file v4.1
+#Version 4.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List locals
+fld public java.util.List stack
+fld public java.util.Map uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds dualCitizens,mainSubroutine,subroutineHeads
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,changed,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List localVariables
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-5.0.4.txt b/asm-commons/src/test/resources/sigtest-5.0.4.txt
new file mode 100644
index 00000000..d6e3ef86
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-5.0.4.txt
@@ -0,0 +1,782 @@
+#Signature file v4.1
+#Version 5.0.4
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List locals
+fld public java.util.List stack
+fld public java.util.Map uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$AnalyzerAdapter,labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,class$org$objectweb$asm$commons$GeneratorAdapter,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$InstructionAdapter
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds class$org$objectweb$asm$commons$JSRInlinerAdapter,dualCitizens,mainSubroutine,subroutineHeads
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,changed,class$org$objectweb$asm$commons$LocalVariablesSorter,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,class$org$objectweb$asm$commons$SerialVersionUIDAdder,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleLocalVariableAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List localVariables
+fld public java.util.List parameters
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleLocalVariableAnnotations
+fld public java.util.List visibleTypeAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$tree$MethodNode,visited
+
diff --git a/asm-commons/src/test/resources/sigtest-5.0.txt b/asm-commons/src/test/resources/sigtest-5.0.txt
new file mode 100644
index 00000000..49fb10a5
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-5.0.txt
@@ -0,0 +1,781 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List locals
+fld public java.util.List stack
+fld public java.util.Map uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$AnalyzerAdapter,labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,class$org$objectweb$asm$commons$GeneratorAdapter,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$InstructionAdapter
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds class$org$objectweb$asm$commons$JSRInlinerAdapter,dualCitizens,mainSubroutine,subroutineHeads
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,changed,class$org$objectweb$asm$commons$LocalVariablesSorter,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,class$org$objectweb$asm$commons$SerialVersionUIDAdder,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleLocalVariableAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List localVariables
+fld public java.util.List parameters
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleLocalVariableAnnotations
+fld public java.util.List visibleTypeAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$tree$MethodNode,visited
+
diff --git a/asm-commons/src/test/resources/sigtest-5.1.txt b/asm-commons/src/test/resources/sigtest-5.1.txt
new file mode 100644
index 00000000..2ef223e9
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-5.1.txt
@@ -0,0 +1,863 @@
+#Signature file v4.1
+#Version 5.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List locals
+fld public java.util.List stack
+fld public java.util.Map uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$AnalyzerAdapter,labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+hfds remapper
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,class$org$objectweb$asm$commons$GeneratorAdapter,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$commons$InstructionAdapter
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds class$org$objectweb$asm$commons$JSRInlinerAdapter,dualCitizens,mainSubroutine,subroutineHeads
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,class$org$objectweb$asm$commons$LocalVariablesSorter,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,class$org$objectweb$asm$commons$SerialVersionUIDAdder,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,v
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleLocalVariableAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List localVariables
+fld public java.util.List parameters
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleLocalVariableAnnotations
+fld public java.util.List visibleTypeAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$tree$MethodNode,visited
+
diff --git a/asm-commons/src/test/resources/sigtest-6.0.txt b/asm-commons/src/test/resources/sigtest-6.0.txt
new file mode 100644
index 00000000..ad21eefd
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-6.0.txt
@@ -0,0 +1,988 @@
+#Signature file v4.1
+#Version 6.0
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+ anno 0 java.lang.annotation.Documented()
+ anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
+ anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE])
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract interface !annotation java.lang.annotation.Documented
+ anno 0 java.lang.annotation.Documented()
+ anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
+ anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
+intf java.lang.annotation.Annotation
+
+CLSS public abstract interface !annotation java.lang.annotation.Retention
+ anno 0 java.lang.annotation.Documented()
+ anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
+ anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
+intf java.lang.annotation.Annotation
+meth public abstract java.lang.annotation.RetentionPolicy value()
+
+CLSS public abstract interface !annotation java.lang.annotation.Target
+ anno 0 java.lang.annotation.Documented()
+ anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
+ anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
+intf java.lang.annotation.Annotation
+meth public abstract java.lang.annotation.ElementType[] value()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds next,value
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+hfds remapper
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds LOGGING,dualCitizens,mainSubroutine,subroutineHeads
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds remapper
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+ anno 0 java.lang.Deprecated()
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,v
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-6.1.txt b/asm-commons/src/test/resources/sigtest-6.1.txt
new file mode 100644
index 00000000..16e2e031
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-6.1.txt
@@ -0,0 +1,966 @@
+#Signature file v4.1
+#Version 6.1
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds OTHER,THIS,branches,constructor,stackFrame,superInitialized
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+hfds remapper
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLDESC,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds LOGGING,dualCitizens,mainSubroutine,subroutineHeads
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,mapping,newLocals
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds DESCRIPTORS,desc,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds remapper
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds access,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,v
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds clinit,counter,name,prefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-6.2.txt b/asm-commons/src/test/resources/sigtest-6.2.txt
new file mode 100644
index 00000000..2e442cdd
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-6.2.txt
@@ -0,0 +1,968 @@
+#Signature file v4.1
+#Version 6.2
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSVUID,hasSVUID,hasStaticInitializer,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-7.0.txt b/asm-commons/src/test/resources/sigtest-7.0.txt
new file mode 100644
index 00000000..1024ab8c
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-7.0.txt
@@ -0,0 +1,977 @@
+#Signature file v4.1
+#Version 7.0
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-7.1.txt b/asm-commons/src/test/resources/sigtest-7.1.txt
new file mode 100644
index 00000000..f38c19d8
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-7.1.txt
@@ -0,0 +1,965 @@
+#Signature file v4.1
+#Version 7.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-7.2.txt b/asm-commons/src/test/resources/sigtest-7.2.txt
new file mode 100644
index 00000000..40819755
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-7.2.txt
@@ -0,0 +1,966 @@
+#Signature file v4.1
+#Version 7.2
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-7.3.1.txt b/asm-commons/src/test/resources/sigtest-7.3.1.txt
new file mode 100644
index 00000000..ff0efa66
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-7.3.1.txt
@@ -0,0 +1,994 @@
+#Signature file v4.1
+#Version 7.3.1
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-8.0.1.txt b/asm-commons/src/test/resources/sigtest-8.0.1.txt
new file mode 100644
index 00000000..a613c951
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-8.0.1.txt
@@ -0,0 +1,997 @@
+#Signature file v4.1
+#Version 8.0.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapRecordComponentName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-9.0.txt b/asm-commons/src/test/resources/sigtest-9.0.txt
new file mode 100644
index 00000000..738b5096
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-9.0.txt
@@ -0,0 +1,1001 @@
+#Signature file v4.1
+#Version 9.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapRecordComponentName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-9.1.txt b/asm-commons/src/test/resources/sigtest-9.1.txt
new file mode 100644
index 00000000..99069044
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-9.1.txt
@@ -0,0 +1,1012 @@
+#Signature file v4.1
+#Version 9.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final java.lang.String descriptor
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapRecordComponentName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-9.2.txt b/asm-commons/src/test/resources/sigtest-9.2.txt
new file mode 100644
index 00000000..2c5ab703
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-9.2.txt
@@ -0,0 +1,1013 @@
+#Signature file v4.1
+#Version 9.2
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final java.lang.String descriptor
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapRecordComponentName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-commons/src/test/resources/sigtest-9.4.txt b/asm-commons/src/test/resources/sigtest-9.4.txt
new file mode 100644
index 00000000..9b8a1e11
--- /dev/null
+++ b/asm-commons/src/test/resources/sigtest-9.4.txt
@@ -0,0 +1,1021 @@
+#Signature file v4.1
+#Version 9.4
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor getDelegate()
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.ClassVisitor getDelegate()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.MethodVisitor getDelegate()
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor getDelegate()
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM10_EXPERIMENTAL = 17432576
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V19 = 63
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V20 = 64
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.RecordComponentVisitor delegate
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.commons.AdviceAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld protected int methodAccess
+fld protected java.lang.String methodDesc
+intf org.objectweb.asm.Opcodes
+meth protected void onMethodEnter()
+meth protected void onMethodExit(int)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitCode()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.commons.GeneratorAdapter
+hfds INVALID_OPCODE,OTHER,UNINITIALIZED_THIS,forwardJumpStackFrames,isConstructor,stackFrame,superClassConstructorCalled
+
+CLSS public org.objectweb.asm.commons.AnalyzerAdapter
+cons protected init(int,java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(java.lang.String,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld public java.util.List<java.lang.Object> locals
+fld public java.util.List<java.lang.Object> stack
+fld public java.util.Map<java.lang.Object,java.lang.Object> uninitializedTypes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds labels,maxLocals,maxStack,owner
+
+CLSS public org.objectweb.asm.commons.AnnotationRemapper
+cons protected init(int,java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(java.lang.String,org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final java.lang.String descriptor
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.commons.ClassRemapper
+cons protected init(int,org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+fld protected java.lang.String className
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.FieldVisitor createFieldRemapper(org.objectweb.asm.FieldVisitor)
+meth protected org.objectweb.asm.MethodVisitor createMethodRemapper(org.objectweb.asm.MethodVisitor)
+meth protected org.objectweb.asm.ModuleVisitor createModuleRemapper(org.objectweb.asm.ModuleVisitor)
+meth protected org.objectweb.asm.RecordComponentVisitor createRecordComponentRemapper(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.commons.CodeSizeEvaluator
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+intf org.objectweb.asm.Opcodes
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public int getMaxSize()
+meth public int getMinSize()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds maxSize,minSize
+
+CLSS public org.objectweb.asm.commons.FieldRemapper
+cons protected init(int,org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.commons.GeneratorAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+cons public init(int,org.objectweb.asm.commons.Method,java.lang.String,org.objectweb.asm.Type[],org.objectweb.asm.ClassVisitor)
+cons public init(int,org.objectweb.asm.commons.Method,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String)
+fld public final static int ADD = 96
+fld public final static int AND = 126
+fld public final static int DIV = 108
+fld public final static int EQ = 153
+fld public final static int GE = 156
+fld public final static int GT = 157
+fld public final static int LE = 158
+fld public final static int LT = 155
+fld public final static int MUL = 104
+fld public final static int NE = 154
+fld public final static int NEG = 116
+fld public final static int OR = 128
+fld public final static int REM = 112
+fld public final static int SHL = 120
+fld public final static int SHR = 122
+fld public final static int SUB = 100
+fld public final static int USHR = 124
+fld public final static int XOR = 130
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth public !varargs void invokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public int getAccess()
+meth public java.lang.String getName()
+meth public org.objectweb.asm.Label mark()
+meth public org.objectweb.asm.Label newLabel()
+meth public org.objectweb.asm.Type getLocalType(int)
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public void arrayLength()
+meth public void arrayLoad(org.objectweb.asm.Type)
+meth public void arrayStore(org.objectweb.asm.Type)
+meth public void box(org.objectweb.asm.Type)
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void catchException(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Type)
+meth public void checkCast(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void endMethod()
+meth public void getField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void getStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void ifCmp(org.objectweb.asm.Type,int,org.objectweb.asm.Label)
+meth public void ifICmp(int,org.objectweb.asm.Label)
+meth public void ifNonNull(org.objectweb.asm.Label)
+meth public void ifNull(org.objectweb.asm.Label)
+meth public void ifZCmp(int,org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokeConstructor(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeInterface(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeStatic(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void invokeVirtual(org.objectweb.asm.Type,org.objectweb.asm.commons.Method)
+meth public void loadArg(int)
+meth public void loadArgArray()
+meth public void loadArgs()
+meth public void loadArgs(int,int)
+meth public void loadLocal(int)
+meth public void loadLocal(int,org.objectweb.asm.Type)
+meth public void loadThis()
+meth public void mark(org.objectweb.asm.Label)
+meth public void math(int,org.objectweb.asm.Type)
+meth public void monitorEnter()
+meth public void monitorExit()
+meth public void newArray(org.objectweb.asm.Type)
+meth public void newInstance(org.objectweb.asm.Type)
+meth public void not()
+meth public void pop()
+meth public void pop2()
+meth public void push(boolean)
+meth public void push(double)
+meth public void push(float)
+meth public void push(int)
+meth public void push(java.lang.String)
+meth public void push(long)
+meth public void push(org.objectweb.asm.ConstantDynamic)
+meth public void push(org.objectweb.asm.Handle)
+meth public void push(org.objectweb.asm.Type)
+meth public void putField(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void putStatic(org.objectweb.asm.Type,java.lang.String,org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void returnValue()
+meth public void storeArg(int)
+meth public void storeLocal(int)
+meth public void storeLocal(int,org.objectweb.asm.Type)
+meth public void swap()
+meth public void swap(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator)
+meth public void tableSwitch(int[],org.objectweb.asm.commons.TableSwitchGenerator,boolean)
+meth public void throwException()
+meth public void throwException(org.objectweb.asm.Type,java.lang.String)
+meth public void unbox(org.objectweb.asm.Type)
+meth public void valueOf(org.objectweb.asm.Type)
+supr org.objectweb.asm.commons.LocalVariablesSorter
+hfds BOOLEAN_TYPE,BOOLEAN_VALUE,BYTE_TYPE,CHARACTER_TYPE,CHAR_VALUE,CLASS_DESCRIPTOR,DOUBLE_TYPE,DOUBLE_VALUE,FLOAT_TYPE,FLOAT_VALUE,INTEGER_TYPE,INT_VALUE,LONG_TYPE,LONG_VALUE,NUMBER_TYPE,OBJECT_TYPE,SHORT_TYPE,access,argumentTypes,localTypes,name,returnType
+
+CLSS public org.objectweb.asm.commons.InstructionAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor)
+fld public final static org.objectweb.asm.Type OBJECT_TYPE
+meth public !varargs void tableswitch(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public void aconst(java.lang.Object)
+meth public void add(org.objectweb.asm.Type)
+meth public void aload(org.objectweb.asm.Type)
+meth public void and(org.objectweb.asm.Type)
+meth public void anew(org.objectweb.asm.Type)
+meth public void areturn(org.objectweb.asm.Type)
+meth public void arraylength()
+meth public void astore(org.objectweb.asm.Type)
+meth public void athrow()
+meth public void cast(org.objectweb.asm.Type,org.objectweb.asm.Type)
+meth public void cconst(org.objectweb.asm.ConstantDynamic)
+meth public void checkcast(org.objectweb.asm.Type)
+meth public void cmpg(org.objectweb.asm.Type)
+meth public void cmpl(org.objectweb.asm.Type)
+meth public void dconst(double)
+meth public void div(org.objectweb.asm.Type)
+meth public void dup()
+meth public void dup2()
+meth public void dup2X1()
+meth public void dup2X2()
+meth public void dupX1()
+meth public void dupX2()
+meth public void fconst(float)
+meth public void getfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void getstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void goTo(org.objectweb.asm.Label)
+meth public void hconst(org.objectweb.asm.Handle)
+meth public void iconst(int)
+meth public void ifacmpeq(org.objectweb.asm.Label)
+meth public void ifacmpne(org.objectweb.asm.Label)
+meth public void ifeq(org.objectweb.asm.Label)
+meth public void ifge(org.objectweb.asm.Label)
+meth public void ifgt(org.objectweb.asm.Label)
+meth public void ificmpeq(org.objectweb.asm.Label)
+meth public void ificmpge(org.objectweb.asm.Label)
+meth public void ificmpgt(org.objectweb.asm.Label)
+meth public void ificmple(org.objectweb.asm.Label)
+meth public void ificmplt(org.objectweb.asm.Label)
+meth public void ificmpne(org.objectweb.asm.Label)
+meth public void ifle(org.objectweb.asm.Label)
+meth public void iflt(org.objectweb.asm.Label)
+meth public void ifne(org.objectweb.asm.Label)
+meth public void ifnonnull(org.objectweb.asm.Label)
+meth public void ifnull(org.objectweb.asm.Label)
+meth public void iinc(int,int)
+meth public void instanceOf(org.objectweb.asm.Type)
+meth public void invokedynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public void invokeinterface(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokespecial(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokestatic(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String)
+meth public void invokevirtual(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void jsr(org.objectweb.asm.Label)
+meth public void lcmp()
+meth public void lconst(long)
+meth public void load(int,org.objectweb.asm.Type)
+meth public void lookupswitch(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void mark(org.objectweb.asm.Label)
+meth public void monitorenter()
+meth public void monitorexit()
+meth public void mul(org.objectweb.asm.Type)
+meth public void multianewarray(java.lang.String,int)
+meth public void neg(org.objectweb.asm.Type)
+meth public void newarray(org.objectweb.asm.Type)
+meth public void nop()
+meth public void or(org.objectweb.asm.Type)
+meth public void pop()
+meth public void pop2()
+meth public void putfield(java.lang.String,java.lang.String,java.lang.String)
+meth public void putstatic(java.lang.String,java.lang.String,java.lang.String)
+meth public void rem(org.objectweb.asm.Type)
+meth public void ret(int)
+meth public void shl(org.objectweb.asm.Type)
+meth public void shr(org.objectweb.asm.Type)
+meth public void store(int,org.objectweb.asm.Type)
+meth public void sub(org.objectweb.asm.Type)
+meth public void swap()
+meth public void tconst(org.objectweb.asm.Type)
+meth public void ushr(org.objectweb.asm.Type)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+meth public void xor(org.objectweb.asm.Type)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public org.objectweb.asm.commons.JSRInlinerAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+intf org.objectweb.asm.Opcodes
+meth public void visitEnd()
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+supr org.objectweb.asm.tree.MethodNode
+hfds mainSubroutineInsns,sharedSubroutineInsns,subroutinesInsns
+hcls Instantiation
+
+CLSS public org.objectweb.asm.commons.LocalVariablesSorter
+cons protected init(int,int,java.lang.String,org.objectweb.asm.MethodVisitor)
+cons public init(int,java.lang.String,org.objectweb.asm.MethodVisitor)
+fld protected final int firstLocal
+fld protected int nextLocal
+meth protected int newLocalMapping(org.objectweb.asm.Type)
+meth protected void setLocalType(int,org.objectweb.asm.Type)
+meth protected void updateNewLocals(java.lang.Object[])
+meth public int newLocal(org.objectweb.asm.Type)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMaxs(int,int)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds OBJECT_TYPE,remappedLocalTypes,remappedVariableIndices
+
+CLSS public org.objectweb.asm.commons.Method
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.lang.String,org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.String,boolean)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.commons.Method getMethod(java.lang.reflect.Method)
+supr java.lang.Object
+hfds PRIMITIVE_TYPE_DESCRIPTORS,descriptor,name
+
+CLSS public org.objectweb.asm.commons.MethodRemapper
+cons protected init(int,org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleHashesAttribute
+cons public init()
+cons public init(java.lang.String,java.util.List<java.lang.String>,java.util.List<byte[]>)
+fld public java.lang.String algorithm
+fld public java.util.List<byte[]> hashes
+fld public java.util.List<java.lang.String> modules
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.ModuleRemapper
+cons protected init(int,org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.commons.ModuleResolutionAttribute
+cons public init()
+cons public init(int)
+fld public final static int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1
+fld public final static int RESOLUTION_WARN_DEPRECATED = 2
+fld public final static int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4
+fld public final static int RESOLUTION_WARN_INCUBATING = 8
+fld public int resolution
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public final org.objectweb.asm.commons.ModuleTargetAttribute
+cons public init()
+cons public init(java.lang.String)
+fld public java.lang.String platform
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+supr org.objectweb.asm.Attribute
+
+CLSS public org.objectweb.asm.commons.RecordComponentRemapper
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.commons.Remapper)
+fld protected final org.objectweb.asm.commons.Remapper remapper
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(java.lang.String,org.objectweb.asm.AnnotationVisitor)
+meth protected org.objectweb.asm.AnnotationVisitor createAnnotationRemapper(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public abstract org.objectweb.asm.commons.Remapper
+cons public init()
+meth protected org.objectweb.asm.signature.SignatureVisitor createRemappingSignatureAdapter(org.objectweb.asm.signature.SignatureVisitor)
+meth protected org.objectweb.asm.signature.SignatureVisitor createSignatureRemapper(org.objectweb.asm.signature.SignatureVisitor)
+meth public java.lang.Object mapValue(java.lang.Object)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapDesc(java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInnerClassName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodDesc(java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapModuleName(java.lang.String)
+meth public java.lang.String mapPackageName(java.lang.String)
+meth public java.lang.String mapRecordComponentName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapSignature(java.lang.String,boolean)
+meth public java.lang.String mapType(java.lang.String)
+meth public java.lang.String[] mapTypes(java.lang.String[])
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.commons.SerialVersionUIDAdder
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor)
+meth protected byte[] computeSHAdigest(byte[])
+meth protected long computeSVUID() throws java.io.IOException
+meth protected void addSVUID(long)
+meth public boolean hasSVUID()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+supr org.objectweb.asm.ClassVisitor
+hfds CLINIT,access,computeSvuid,hasStaticInitializer,hasSvuid,interfaces,name,svuidConstructors,svuidFields,svuidMethods
+hcls Item
+
+CLSS public org.objectweb.asm.commons.SignatureRemapper
+cons protected init(int,org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+cons public init(org.objectweb.asm.signature.SignatureVisitor,org.objectweb.asm.commons.Remapper)
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds classNames,remapper,signatureVisitor
+
+CLSS public org.objectweb.asm.commons.SimpleRemapper
+cons public init(java.lang.String,java.lang.String)
+cons public init(java.util.Map<java.lang.String,java.lang.String>)
+meth public java.lang.String map(java.lang.String)
+meth public java.lang.String mapAnnotationAttributeName(java.lang.String,java.lang.String)
+meth public java.lang.String mapFieldName(java.lang.String,java.lang.String,java.lang.String)
+meth public java.lang.String mapInvokeDynamicMethodName(java.lang.String,java.lang.String)
+meth public java.lang.String mapMethodName(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.commons.Remapper
+hfds mapping
+
+CLSS public org.objectweb.asm.commons.StaticInitMerger
+cons protected init(int,java.lang.String,org.objectweb.asm.ClassVisitor)
+cons public init(java.lang.String,org.objectweb.asm.ClassVisitor)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.ClassVisitor
+hfds mergedClinitVisitor,numClinitMethods,owner,renamedClinitMethodPrefix
+
+CLSS public abstract interface org.objectweb.asm.commons.TableSwitchGenerator
+meth public abstract void generateCase(int,org.objectweb.asm.Label)
+meth public abstract void generateDefault()
+
+CLSS public org.objectweb.asm.commons.TryCatchBlockSorter
+cons protected init(int,org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(org.objectweb.asm.MethodVisitor,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitEnd()
+supr org.objectweb.asm.tree.MethodNode
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons protected init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
diff --git a/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java
new file mode 100644
index 00000000..ee0ad099
--- /dev/null
+++ b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java
@@ -0,0 +1,389 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.provider.Arguments;
+
+/**
+ * Base class for the ASM tests. ASM can be used to read, write or transform any Java class, ranging
+ * from very old (e.g. JDK 1.3) to very recent classes, containing all possible class file
+ * structures. ASM can also be used with different variants of its API (ASM4, ASM5, ASM6, etc). In
+ * order to test it thoroughly, it is therefore necessary to run read, write and transform tests,
+ * for each API version, and for each class in a set of classes containing all possible class file
+ * structures. The purpose of this class is to automate this process. For this it relies on:
+ *
+ * <ul>
+ * <li>a small set of hand-crafted classes designed to contain as much class file structures as
+ * possible (it is impossible to represent all possible bytecode sequences). These classes are
+ * called "precompiled classes" below, because they are not compiled as part of the build.
+ * Instead, they have been compiled beforehand with the appropriate JDKs (e.g. with the JDK
+ * 1.3, 1.5, etc).
+ * <li>the JUnit framework for parameterized tests. Using the {@link #allClassesAndAllApis()}
+ * method, selected test methods can be instantiated for each possible (precompiled class, ASM
+ * API) tuple.
+ * </ul>
+ *
+ * <p>For instance, to run a test on all the precompiled classes, with all the APIs, use a subclass
+ * such as the following:
+ *
+ * <pre>
+ * public class MyParameterizedTest extends AsmTest {
+ *
+ * &#64;ParameterizedTest
+ * &#64;MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ * public void testSomeFeature(PrecompiledClass classParameter, Api apiParameter) {
+ * byte[] b = classParameter.getBytes();
+ * ClassWriter classWriter = new ClassWriter(apiParameter.value(), 0);
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AsmTest {
+
+ /** The size of the temporary byte array used to read class input streams chunk by chunk. */
+ private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
+
+ /**
+ * MethodSource name to be used in parameterized tests that must be instantiated for all possible
+ * (precompiled class, api) pairs.
+ */
+ public static final String ALL_CLASSES_AND_ALL_APIS = "allClassesAndAllApis";
+
+ /**
+ * MethodSource name to be used in parameterized tests that must be instantiated for all
+ * precompiled classes, with the latest api.
+ */
+ public static final String ALL_CLASSES_AND_LATEST_API = "allClassesAndLatestApi";
+
+ /**
+ * The expected pattern (i.e. regular expression) that ASM's UnsupportedOperationException
+ * messages are supposed to match.
+ */
+ public static final String UNSUPPORTED_OPERATION_MESSAGE_PATTERN = ".* requires ASM[56789].*";
+
+ /** JDK version with the corresponding ASM version. */
+ enum JdkVersion {
+ JDK7(7, Api.ASM4),
+ JDK8(8, Api.ASM5),
+ JDK9(9, Api.ASM6),
+ JDK11(11, Api.ASM7),
+ JDK14(14, Api.ASM8),
+ JDK15(15, Api.ASM9);
+
+ private final int majorVersion;
+ private final Api minimumApi;
+
+ JdkVersion(final int majorVersion, final Api minimumApi) {
+ this.majorVersion = majorVersion;
+ this.minimumApi = minimumApi;
+ }
+
+ /**
+ * Returns the major version of the current JDK version.
+ *
+ * @return the major version of the current JDK version.
+ */
+ public int majorVersion() {
+ return majorVersion;
+ }
+
+ /**
+ * Returns the minimum ASM Api version supporting the current JDK version.
+ *
+ * @return the minimum ASM Api version supporting the current JDK version.
+ */
+ public Api minimumApi() {
+ return minimumApi;
+ }
+ }
+
+ /**
+ * A precompiled class, hand-crafted to contain some set of class file structures. These classes
+ * are not compiled as part of the build. Instead, they have been compiled beforehand, with the
+ * appropriate JDKs (including some now very hard to download and install).
+ */
+ public enum PrecompiledClass {
+ DEFAULT_PACKAGE("DefaultPackage"),
+ JDK3_ALL_INSTRUCTIONS("jdk3.AllInstructions"),
+ JDK3_ALL_STRUCTURES("jdk3.AllStructures"),
+ JDK3_ANONYMOUS_INNER_CLASS("jdk3.AllStructures$1"),
+ JDK3_ARTIFICIAL_STRUCTURES("jdk3.ArtificialStructures"),
+ JDK3_INNER_CLASS("jdk3.AllStructures$InnerClass"),
+ JDK3_LARGE_METHOD("jdk3.LargeMethod"),
+ JDK3_SUB_OPTIMAL_MAX_STACK_AND_LOCALS("jdk3.SubOptimalMaxStackAndLocals"),
+ JDK5_ALL_INSTRUCTIONS("jdk5.AllInstructions"),
+ JDK5_ALL_STRUCTURES("jdk5.AllStructures"),
+ JDK5_ANNOTATION("jdk5.AllStructures$InvisibleAnnotation"),
+ JDK5_ENUM("jdk5.AllStructures$EnumClass"),
+ JDK5_LOCAL_CLASS("jdk5.AllStructures$1LocalClass"),
+ JDK8_ALL_FRAMES("jdk8.AllFrames", JdkVersion.JDK8),
+ JDK8_ALL_INSTRUCTIONS("jdk8.AllInstructions", JdkVersion.JDK8),
+ JDK8_ALL_STRUCTURES("jdk8.AllStructures", JdkVersion.JDK8),
+ JDK8_ANONYMOUS_INNER_CLASS("jdk8.AllStructures$1", JdkVersion.JDK8),
+ JDK8_ARTIFICIAL_STRUCTURES("jdk8.Artificial$()$Structures", JdkVersion.JDK8),
+ JDK8_INNER_CLASS("jdk8.AllStructures$InnerClass", JdkVersion.JDK8),
+ JDK8_LARGE_METHOD("jdk8.LargeMethod", JdkVersion.JDK8),
+ JDK9_MODULE("jdk9.module-info", JdkVersion.JDK9),
+ JDK11_ALL_INSTRUCTIONS("jdk11.AllInstructions", JdkVersion.JDK11),
+ JDK11_ALL_STRUCTURES("jdk11.AllStructures", JdkVersion.JDK11),
+ JDK11_ALL_STRUCTURES_NESTED("jdk11.AllStructures$Nested", JdkVersion.JDK11),
+ JDK14_ALL_STRUCTURES_RECORD("jdk14.AllStructures$RecordSubType", JdkVersion.JDK14, true),
+ JDK14_ALL_STRUCTURES_EMPTY_RECORD("jdk14.AllStructures$EmptyRecord", JdkVersion.JDK14, true),
+ JDK15_ALL_STRUCTURES("jdk15.AllStructures", JdkVersion.JDK15, true);
+
+ private final String name;
+ private final JdkVersion jdkVersion;
+ private final boolean preview;
+ private byte[] bytes;
+
+ PrecompiledClass(final String name, final JdkVersion jdkVersion, final boolean preview) {
+ this.name = name;
+ this.jdkVersion = jdkVersion;
+ this.preview = preview;
+ }
+
+ PrecompiledClass(final String name, final JdkVersion jdkVersion) {
+ this(name, jdkVersion, false);
+ }
+
+ PrecompiledClass(final String name) {
+ this(name, JdkVersion.JDK7, false);
+ }
+
+ /**
+ * Returns the fully qualified name of this class.
+ *
+ * @return the fully qualified name of this class.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the internal name of this class.
+ *
+ * @return the internal name of this class.
+ */
+ public String getInternalName() {
+ return name.endsWith(ClassFile.MODULE_INFO) ? ClassFile.MODULE_INFO : name.replace('.', '/');
+ }
+
+ /**
+ * Returns true if this class was compiled with a JDK which is more recent than the given ASM
+ * API. For instance, returns true for a class compiled with the JDK 1.8 if the ASM API version
+ * is ASM4.
+ *
+ * @param api an ASM API version.
+ * @return whether this class was compiled with a JDK which is more recent than api.
+ */
+ public boolean isMoreRecentThan(final Api api) {
+ return api.value() < jdkVersion.minimumApi().value();
+ }
+
+ /**
+ * Returns true if this class was compiled with a JDK which is not compatible with the JDK used
+ * to run the tests.
+ *
+ * @return true if this class was compiled with a JDK which is not compatible with the JDK used
+ * to run the tests.
+ */
+ public boolean isNotCompatibleWithCurrentJdk() {
+ if (preview) {
+ if (!Util.previewFeatureEnabled()) {
+ return true;
+ }
+ return Util.getMajorJavaVersion() != jdkVersion.majorVersion();
+ }
+ return Util.getMajorJavaVersion() < jdkVersion.majorVersion();
+ }
+
+ /**
+ * Returns the content of this class.
+ *
+ * @return the content of this class.
+ */
+ public byte[] getBytes() {
+ if (bytes == null) {
+ bytes = AsmTest.getBytes(name, ".class");
+ }
+ return bytes.clone();
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * An invalid class, hand-crafted to contain some set of invalid class file structures. These
+ * classes are not compiled as part of the build. Instead, they have been compiled beforehand, and
+ * then manually edited to introduce errors.
+ */
+ public enum InvalidClass {
+ INVALID_BYTECODE_OFFSET("invalid.InvalidBytecodeOffset"),
+ INVALID_CLASS_VERSION("invalid.InvalidClassVersion"),
+ INVALID_CODE_LENGTH("invalid.InvalidCodeLength"),
+ INVALID_CONSTANT_POOL_INDEX("invalid.InvalidConstantPoolIndex"),
+ INVALID_CONSTANT_POOL_REFERENCE("invalid.InvalidConstantPoolReference"),
+ INVALID_CP_INFO_TAG("invalid.InvalidCpInfoTag"),
+ INVALID_ELEMENT_VALUE("invalid.InvalidElementValue"),
+ INVALID_INSN_TYPE_ANNOTATION_TARGET_TYPE("invalid.InvalidInsnTypeAnnotationTargetType"),
+ INVALID_OPCODE("invalid.InvalidOpcode"),
+ INVALID_SOURCE_DEBUG_EXTENSION("invalid.InvalidSourceDebugExtension"),
+ INVALID_STACK_MAP_FRAME_TYPE("invalid.InvalidStackMapFrameType"),
+ INVALID_TYPE_ANNOTATION_TARGET_TYPE("invalid.InvalidTypeAnnotationTargetType"),
+ INVALID_VERIFICATION_TYPE_INFO("invalid.InvalidVerificationTypeInfo"),
+ INVALID_WIDE_OPCODE("invalid.InvalidWideOpcode");
+
+ private final String name;
+
+ InvalidClass(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the fully qualified name of this class.
+ *
+ * @return the fully qualified name of this class.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the content of this class.
+ *
+ * @return the content of this class.
+ */
+ public byte[] getBytes() {
+ return AsmTest.getBytes(name, ".clazz");
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /** An ASM API version. */
+ public enum Api {
+ ASM4("ASM4", 4 << 16),
+ ASM5("ASM5", 5 << 16),
+ ASM6("ASM6", 6 << 16),
+ ASM7("ASM7", 7 << 16),
+ ASM8("ASM8", 8 << 16),
+ ASM9("ASM9", 9 << 16),
+ ;
+
+ private final String name;
+ private final int value;
+
+ Api(final String name, final int value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Returns the int value of this version, as expected by ASM.
+ *
+ * @return one of the ASM4, ASM5, ASM6, ASM7, ASM8 or ASM9 constants from the ASM Opcodes
+ * interface.
+ */
+ public int value() {
+ return value;
+ }
+
+ /**
+ * Returns a human readable symbol corresponding to this version.
+ *
+ * @return one of "ASM4", "ASM5", "ASM6" "ASM7", "ASM8" or "ASM9".
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * Builds a list of test arguments for a parameterized test. Parameterized test cases annotated
+ * with {@code @MethodSource("allClassesAndAllApis")} will be executed on all the possible
+ * (precompiledClass, api) pairs.
+ *
+ * @return all the possible (precompiledClass, api) pairs, for all the precompiled classes and all
+ * the given ASM API versions.
+ */
+ public static Stream<Arguments> allClassesAndAllApis() {
+ return classesAndApis(Api.values());
+ }
+
+ /**
+ * Builds a list of test arguments for a parameterized test. Parameterized test cases annotated
+ * with {@code @MethodSource("allClassesAndLatestApi")} will be executed on all the precompiled
+ * classes, with the latest api.
+ *
+ * @return all the possible (precompiledClass, ASM9) pairs, for all the precompiled classes.
+ */
+ public static Stream<Arguments> allClassesAndLatestApi() {
+ return classesAndApis(Api.ASM9);
+ }
+
+ private static Stream<Arguments> classesAndApis(final Api... apis) {
+ return Arrays.stream(PrecompiledClass.values())
+ .flatMap(
+ precompiledClass ->
+ Arrays.stream(apis).map(api -> Arguments.of(precompiledClass, api)));
+ }
+
+ private static byte[] getBytes(final String name, final String extension) {
+ String resourceName = name.replace('.', '/') + extension;
+ try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(resourceName)) {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Class not found " + name);
+ }
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] data = new byte[INPUT_STREAM_DATA_CHUNK_SIZE];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
+ outputStream.write(data, 0, bytesRead);
+ }
+ outputStream.flush();
+ return outputStream.toByteArray();
+ } catch (IOException e) {
+ throw new ClassFormatException("Can't read " + name, e);
+ }
+ }
+}
diff --git a/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java b/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java
new file mode 100644
index 00000000..c4fc9aba
--- /dev/null
+++ b/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java
@@ -0,0 +1,2637 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+
+/**
+ * A Java class file, whose content can be returned as a verbose, human "readable" string. As an
+ * example, the string representation of the HelloWorld class, obtained with the {@link #toString()}
+ * method, is:
+ *
+ * <pre>
+ * magic: -889275714
+ * minor_version: 0
+ * major_version: 49
+ * access_flags: 33
+ * this_class: ConstantClassInfo HelloWorld
+ * super_class: ConstantClassInfo java/lang/Object
+ * interfaces_count: 0
+ * fields_count: 0
+ * methods_count: 2
+ * access_flags: 1
+ * name_index: &lt;init&gt;
+ * descriptor_index: ()V
+ * attributes_count: 1
+ * attribute_name_index: Code
+ * max_stack: 1
+ * max_locals: 1
+ * 0: 25 0
+ * 1: 183 ConstantMethodRefInfo java/lang/Object.&lt;init&gt;()V
+ * 2: 177
+ * exception_table_length: 0
+ * attributes_count: 2
+ * attribute_name_index: LineNumberTable
+ * line_number_table_length: 1
+ * start_pc: &lt;0&gt;
+ * line_number: 31
+ * attribute_name_index: LocalVariableTable
+ * local_variable_table_length: 1
+ * start_pc: &lt;0&gt;
+ * length: &lt;3&gt;
+ * name_index: this
+ * descriptor_index: LHelloWorld;
+ * index: 0
+ * access_flags: 9
+ * name_index: main
+ * descriptor_index: ([Ljava/lang/String;)V
+ * attributes_count: 1
+ * attribute_name_index: Code
+ * max_stack: 2
+ * max_locals: 1
+ * 0: 178 ConstantFieldRefInfo java/lang/System.outLjava/io/PrintStream;
+ * 1: 18 ConstantStringInfo Hello, world!
+ * 2: 182 ConstantMethodRefInfo java/io/PrintStream.println(Ljava/lang/String;)V
+ * 3: 177
+ * exception_table_length: 0
+ * attributes_count: 2
+ * attribute_name_index: LineNumberTable
+ * line_number_table_length: 2
+ * start_pc: &lt;0&gt;
+ * line_number: 33
+ * start_pc: &lt;3&gt;
+ * line_number: 34
+ * attribute_name_index: LocalVariableTable
+ * local_variable_table_length: 1
+ * start_pc: &lt;0&gt;
+ * length: &lt;4&gt;
+ * name_index: args
+ * descriptor_index: [Ljava/lang/String;
+ * index: 0
+ * attributes_count: 1
+ * attribute_name_index: SourceFile
+ * sourcefile_index: HelloWorld.java
+ * </pre>
+ *
+ * <p>This class is used to compare classes in unit tests. Its source code is as close as possible
+ * to the Java Virtual Machine specification for ease of reference. The constant pool and bytecode
+ * offsets are abstracted away so that two classes which differ only by their constant pool or low
+ * level byte code instruction representation (e.g. a ldc vs. a ldc_w) are still considered equal.
+ * Likewise, attributes (resp. type annotations) are re-ordered into alphabetical order, so that two
+ * classes which differ only via the ordering of their attributes (resp. type annotations) are still
+ * considered equal.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassFile {
+
+ /** The name of JDK9 module classes. */
+ static final String MODULE_INFO = "module-info";
+
+ /** The binary content of a Java class file. */
+ private final byte[] classBytes;
+
+ /** The name of the class contained in this class file, lazily computed. */
+ private String className;
+
+ /** The dump of the constant pool of {@link #classBytes}, lazily computed. */
+ private String constantPoolDump;
+
+ /** The dump of {@link #classBytes}, lazily computed. */
+ private String dump;
+
+ /**
+ * Constructs a new ClassFile instance.
+ *
+ * @param classBytes the binary content of a Java class file.
+ */
+ public ClassFile(final byte[] classBytes) {
+ this.classBytes = classBytes;
+ }
+
+ /**
+ * Returns a string representation of the constant pool of the class contained in this class file.
+ *
+ * @return a string representation of the constant pool of the class contained in this class file.
+ */
+ public String getConstantPoolDump() {
+ if (constantPoolDump == null) {
+ computeNameAndDumps();
+ }
+ return constantPoolDump;
+ }
+
+ /**
+ * Returns a new instance of the class contained in this class file. The class is loaded in a new
+ * class loader.
+ *
+ * @return a new instance of the class, or {@literal null} if the class is abstract, is an enum,
+ * or a module info.
+ * @throws ReflectiveOperationException if the class is invalid or if an error occurs in its
+ * constructor.
+ */
+ public Object newInstance() throws ReflectiveOperationException {
+ if (className == null) {
+ computeNameAndDumps();
+ }
+ return newInstance(className, classBytes);
+ }
+
+ /**
+ * Returns a new instance of the given class. The class is loaded in a new class loader.
+ *
+ * @param className the name of the class to load.
+ * @param classContent the content of the class to load.
+ * @return a new instance of the class, or {@literal null} if the class is abstract, is an enum,
+ * or a module info.
+ * @throws ReflectiveOperationException if the class is invalid or if an error occurs in its
+ * constructor.
+ */
+ static Object newInstance(final String className, final byte[] classContent)
+ throws ReflectiveOperationException {
+ if (className.endsWith(MODULE_INFO)) {
+ if (Util.getMajorJavaVersion() < 9) {
+ throw new UnsupportedClassVersionError("Module info is not supported before JDK 9");
+ } else {
+ return null;
+ }
+ }
+ ByteClassLoader byteClassLoader = new ByteClassLoader(className, classContent);
+ Class<?> clazz = byteClassLoader.loadClass(className);
+ // Make sure the class is loaded from the given byte array, excluding any other source.
+ if (!byteClassLoader.classLoaded()) {
+ // This should never happen, given the implementation of ByteClassLoader.
+ throw new AssertionError("Class " + className + " loaded from wrong source");
+ }
+ if (!clazz.isEnum() && (clazz.getModifiers() & Modifier.ABSTRACT) == 0) {
+ Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
+ ArrayList<Object> arguments = new ArrayList<>();
+ for (Class<?> parameterType : constructor.getParameterTypes()) {
+ arguments.add(Array.get(Array.newInstance(parameterType, 1), 0));
+ }
+ constructor.setAccessible(true); // NOPMD(AvoidAccessibilityAlteration): ok for tests.
+ return constructor.newInstance(arguments.toArray(new Object[0]));
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether the given class file is the same as this one.
+ *
+ * @return true if 'other' is a {@link ClassFile} with the same string representation.
+ * @throws ClassFormatException if the class content can't be parsed.
+ */
+ @Override
+ public boolean equals(final Object other) {
+ if (other instanceof ClassFile) {
+ return toString().equals(other.toString());
+ }
+ return false;
+ }
+
+ /**
+ * Returns the hashcode of this class file.
+ *
+ * @return the hashcode of the string representation of this class file.
+ * @throws ClassFormatException if the class content can't be parsed.
+ */
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * Returns a string representation of this class file.
+ *
+ * @return a string representation of this class file (see the class comments for more details).
+ * @throws ClassFormatException if the class content can't be parsed.
+ */
+ @Override
+ public String toString() {
+ if (dump == null) {
+ computeNameAndDumps();
+ }
+ return dump;
+ }
+
+ /**
+ * Computes the name and the string representation of the class (and of its constant pool)
+ * contained in this class file.
+ *
+ * @throws ClassFormatException if the class content can't be parsed.
+ */
+ private void computeNameAndDumps() {
+ try {
+ Builder builder = new Builder("ClassFile", /* parent = */ null);
+ Builder constantPoolBuilder = new Builder("ConstantPool", /* parent = */ null);
+ ConstantClassInfo classInfo =
+ dumpClassFile(new Parser(classBytes), builder, constantPoolBuilder);
+ className = classInfo.dump().replace('/', '.');
+ StringBuilder stringBuilder = new StringBuilder();
+ builder.build(stringBuilder);
+ dump = stringBuilder.toString();
+ StringBuilder constantPoolStringBuilder = new StringBuilder();
+ constantPoolBuilder.build(constantPoolStringBuilder);
+ constantPoolDump = constantPoolStringBuilder.toString();
+ } catch (IOException e) {
+ throw new ClassFormatException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Parses and dumps the high level structure of the class.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @param constantPoolBuilder a dump builder for the constant pool.
+ * @return the ConstantClassInfo corresponding to the parsed class.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1">JVMS
+ * 4.1</a>
+ */
+ private static ConstantClassInfo dumpClassFile(
+ final Parser parser, final Builder builder, final Builder constantPoolBuilder)
+ throws IOException {
+ builder.add("magic: ", parser.u4());
+ builder.add("minor_version: ", parser.u2());
+ int majorVersion = parser.u2();
+ if (majorVersion > /* V15 = */ 59) {
+ throw new ClassFormatException("Unsupported class version");
+ }
+ builder.add("major_version: ", majorVersion);
+ int constantPoolCount = parser.u2();
+ int cpIndex = 1;
+ while (cpIndex < constantPoolCount) {
+ CpInfo cpInfo = parseCpInfo(parser, builder);
+ builder.putCpInfo(cpIndex, cpInfo);
+ constantPoolBuilder.putCpInfo(cpIndex, cpInfo);
+ constantPoolBuilder.addCpInfo("constant_pool: ", cpIndex);
+ cpIndex += cpInfo.size();
+ }
+ builder.add("access_flags: ", parser.u2());
+ int thisClass = parser.u2();
+ builder.addCpInfo("this_class: ", thisClass);
+ builder.addCpInfo("super_class: ", parser.u2());
+ int interfaceCount = builder.add("interfaces_count: ", parser.u2());
+ for (int i = 0; i < interfaceCount; ++i) {
+ builder.addCpInfo("interface: ", parser.u2());
+ }
+ int fieldCount = builder.add("fields_count: ", parser.u2());
+ for (int i = 0; i < fieldCount; ++i) {
+ dumpFieldInfo(parser, builder);
+ }
+ int methodCount = builder.add("methods_count: ", parser.u2());
+ for (int i = 0; i < methodCount; ++i) {
+ dumpMethodInfo(parser, builder);
+ }
+ dumpAttributeList(parser, builder);
+ return builder.getCpInfo(thisClass, ConstantClassInfo.class);
+ }
+
+ /**
+ * Parses and dumps a list of attributes.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1">JVMS
+ * 4.1</a>
+ */
+ private static void dumpAttributeList(final Parser parser, final Builder builder)
+ throws IOException {
+ int attributeCount = builder.add("attributes_count: ", parser.u2());
+ SortedBuilder sortedBuilder = builder.addSortedBuilder();
+ for (int i = 0; i < attributeCount; ++i) {
+ dumpAttributeInfo(parser, sortedBuilder);
+ }
+ }
+
+ /**
+ * Parses a cp_info structure.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @return the parsed constant pool item.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4">JVMS
+ * 4.4</a>
+ */
+ private static CpInfo parseCpInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ int tag = parser.u1();
+ switch (tag) {
+ case 7:
+ return new ConstantClassInfo(parser, classContext);
+ case 9:
+ return new ConstantFieldRefInfo(parser, classContext);
+ case 10:
+ return new ConstantMethodRefInfo(parser, classContext);
+ case 11:
+ return new ConstantInterfaceMethodRefInfo(parser, classContext);
+ case 8:
+ return new ConstantStringInfo(parser, classContext);
+ case 3:
+ return new ConstantIntegerInfo(parser);
+ case 4:
+ return new ConstantFloatInfo(parser);
+ case 5:
+ return new ConstantLongInfo(parser);
+ case 6:
+ return new ConstantDoubleInfo(parser);
+ case 12:
+ return new ConstantNameAndTypeInfo(parser, classContext);
+ case 1:
+ return new ConstantUtf8Info(parser);
+ case 15:
+ return new ConstantMethodHandleInfo(parser, classContext);
+ case 16:
+ return new ConstantMethodTypeInfo(parser, classContext);
+ case 17:
+ return new ConstantDynamicInfo(parser, classContext);
+ case 18:
+ return new ConstantInvokeDynamicInfo(parser, classContext);
+ case 19:
+ return new ConstantModuleInfo(parser, classContext);
+ case 20:
+ return new ConstantPackageInfo(parser, classContext);
+ default:
+ throw new ClassFormatException("Invalid constant pool item tag " + tag);
+ }
+ }
+
+ /**
+ * Parses and dumps a field_info structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5">JVMS
+ * 4.5</a>
+ */
+ private static void dumpFieldInfo(final Parser parser, final Builder builder) throws IOException {
+ builder.add("access_flags: ", parser.u2());
+ builder.addCpInfo("name_index: ", parser.u2());
+ builder.addCpInfo("descriptor_index: ", parser.u2());
+ dumpAttributeList(parser, builder);
+ }
+
+ /**
+ * Parses and dumps a method_info structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6">JVMS
+ * 4.6</a>
+ */
+ private static void dumpMethodInfo(final Parser parser, final Builder builder)
+ throws IOException {
+ // method_info has the same top level structure as field_info.
+ dumpFieldInfo(parser, builder);
+ }
+
+ /**
+ * Parses and dumps an attribute_info structure.
+ *
+ * @param parser a class parser.
+ * @param sortedBuilder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
+ * 4.7</a>
+ */
+ private static void dumpAttributeInfo(final Parser parser, final SortedBuilder sortedBuilder)
+ throws IOException {
+ String attributeName = sortedBuilder.getCpInfo(parser.u2()).toString();
+ int attributeLength = parser.u4();
+ Builder builder = sortedBuilder.addBuilder(attributeName);
+ builder.add("attribute_name_index: ", attributeName);
+ if (attributeName.equals("ConstantValue")) {
+ dumpConstantValueAttribute(parser, builder);
+ } else if (attributeName.equals("Code")) {
+ dumpCodeAttribute(parser, builder);
+ } else if (attributeName.equals("StackMapTable")) {
+ dumpStackMapTableAttribute(parser, builder);
+ } else if (attributeName.equals("Exceptions")) {
+ dumpExceptionsAttribute(parser, builder);
+ } else if (attributeName.equals("InnerClasses")) {
+ dumpInnerClassesAttribute(parser, builder);
+ } else if (attributeName.equals("EnclosingMethod")) {
+ dumpEnclosingMethodAttribute(parser, builder);
+ } else if (attributeName.equals("Synthetic")) {
+ dumpSyntheticAttribute();
+ } else if (attributeName.equals("Signature")) {
+ dumpSignatureAttribute(parser, builder);
+ } else if (attributeName.equals("SourceFile")) {
+ dumpSourceFileAttribute(parser, builder);
+ } else if (attributeName.equals("SourceDebugExtension")) {
+ dumpSourceDebugAttribute(attributeLength, parser, builder);
+ } else if (attributeName.equals("LineNumberTable")) {
+ dumpLineNumberTableAttribute(parser, builder);
+ } else if (attributeName.equals("LocalVariableTable")) {
+ dumpLocalVariableTableAttribute(parser, builder);
+ } else if (attributeName.equals("LocalVariableTypeTable")) {
+ dumpLocalVariableTypeTableAttribute(parser, builder);
+ } else if (attributeName.equals("Deprecated")) {
+ dumpDeprecatedAttribute();
+ } else if (attributeName.equals("RuntimeVisibleAnnotations")) {
+ dumpRuntimeVisibleAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("RuntimeInvisibleAnnotations")) {
+ dumpRuntimeInvisibleAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("RuntimeVisibleParameterAnnotations")) {
+ dumpRuntimeVisibleParameterAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("RuntimeInvisibleParameterAnnotations")) {
+ dumpRuntimeInvisibleParameterAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("RuntimeVisibleTypeAnnotations")) {
+ dumpRuntimeVisibleTypeAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("RuntimeInvisibleTypeAnnotations")) {
+ dumpRuntimeInvisibleTypeAnnotationsAttribute(parser, builder);
+ } else if (attributeName.equals("AnnotationDefault")) {
+ dumpAnnotationDefaultAttribute(parser, builder);
+ } else if (attributeName.equals("BootstrapMethods")) {
+ dumpBootstrapMethodsAttribute(parser, builder);
+ } else if (attributeName.equals("MethodParameters")) {
+ dumpMethodParametersAttribute(parser, builder);
+ } else if (attributeName.equals("Module")) {
+ dumpModuleAttribute(parser, builder);
+ } else if (attributeName.equals("ModulePackages")) {
+ dumpModulePackagesAttribute(parser, builder);
+ } else if (attributeName.equals("ModuleMainClass")) {
+ dumpModuleMainClassAttribute(parser, builder);
+ } else if (attributeName.equals("NestHost")) {
+ dumpNestHostAttribute(parser, builder);
+ } else if (attributeName.equals("NestMembers")) {
+ dumpNestMembersAttribute(parser, builder);
+ } else if (attributeName.equals("PermittedSubclasses")) {
+ dumpPermittedSubclassesAttribute(parser, builder);
+ } else if (attributeName.equals("Record")) {
+ dumpRecordAttribute(parser, builder);
+ } else if (attributeName.equals("StackMap")) {
+ dumpStackMapAttribute(parser, builder);
+ } else if (!attributeName.equals("CodeComment") && !attributeName.equals("Comment")) {
+ // Not a standard attribute nor one the of empty non-standard attributes used for tests.
+ throw new ClassFormatException("Unknown attribute " + attributeName);
+ }
+ }
+
+ /**
+ * Parses and dumps a ConstantValue attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.2">JVMS
+ * 4.7.2</a>
+ */
+ private static void dumpConstantValueAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("constantvalue_index: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a Code attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
+ * 4.7.3</a>
+ */
+ private static void dumpCodeAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.add("max_stack: ", parser.u2());
+ builder.add("max_locals: ", parser.u2());
+ int codeLength = parser.u4();
+ dumpInstructions(codeLength, parser, builder);
+ int exceptionCount = builder.add("exception_table_length: ", parser.u2());
+ for (int i = 0; i < exceptionCount; ++i) {
+ builder.addInsnIndex("start_pc: ", parser.u2());
+ builder.addInsnIndex("end_pc: ", parser.u2());
+ builder.addInsnIndex("handler_pc: ", parser.u2());
+ builder.addCpInfo("catch_type: ", parser.u2());
+ }
+ dumpAttributeList(parser, builder);
+ }
+
+ /**
+ * Parses and dumps the bytecode instructions of a method.
+ *
+ * @param codeLength the number of bytes to parse.
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html#jvms-6.5">JVMS
+ * 6.5</a>
+ */
+ private static void dumpInstructions(
+ final int codeLength, final Parser parser, final Builder builder) throws IOException {
+ int bytecodeOffset = 0; // Number of bytes parsed so far.
+ int insnIndex = 0; // Number of instructions parsed so far.
+ while (bytecodeOffset < codeLength) {
+ builder.putInsnIndex(bytecodeOffset, insnIndex);
+ int opcode = parser.u1();
+ int startOffset = bytecodeOffset++;
+ // Instructions are in alphabetical order of their opcode name, as
+ // in the specification. This leads to some duplicated code, but is
+ // done on purpose for ease of reference.
+ switch (opcode) {
+ case 0x32: // aaload
+ case 0x53: // aastore
+ case 0x01: // aconst_null
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x19: // aload
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x2A: // aload_0
+ case 0x2B: // aload_1
+ case 0x2C: // aload_2
+ case 0x2D: // aload_3
+ builder.addInsn(insnIndex, 0x19, opcode - 0x2A);
+ break;
+ case 0xBD: // anewarray
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0xB0: // areturn
+ case 0xBE: // arraylength
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x3A: // astore
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x4B: // astore_0
+ case 0x4C: // astore_1
+ case 0x4D: // astore_2
+ case 0x4E: // astore_3
+ builder.addInsn(insnIndex, 0x3A, opcode - 0x4B);
+ break;
+ case 0xBF: // athrow
+ case 0x33: // baload
+ case 0x54: // bastore
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x10: // bipush
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x34: // caload
+ case 0x55: // castore
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xC0: // checkcast
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0x90: // d2f
+ case 0x8E: // d2i
+ case 0x8F: // d2l
+ case 0x63: // dadd
+ case 0x31: // daload
+ case 0x52: // dastore
+ case 0x98: // dcmpg
+ case 0x97: // dcmpl
+ case 0x0E: // dconst_0
+ case 0x0F: // dconst_1
+ case 0x6F: // ddiv
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x18: // dload
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x26: // dload_0
+ case 0x27: // dload_1
+ case 0x28: // dload_2
+ case 0x29: // dload_3
+ builder.addInsn(insnIndex, 0x18, opcode - 0x26);
+ break;
+ case 0x6B: // dmul
+ case 0x77: // dneg
+ case 0x73: // drem
+ case 0xAF: // dreturn
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x39: // dstore
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x47: // dstore_0
+ case 0x48: // dstore_1
+ case 0x49: // dstore_2
+ case 0x4A: // dstore_3
+ builder.addInsn(insnIndex, 0x39, opcode - 0x47);
+ break;
+ case 0x67: // dsub
+ case 0x59: // dup
+ case 0x5A: // dup_x1
+ case 0x5B: // dup_x2
+ case 0x5C: // dup2
+ case 0x5D: // dup2_x1
+ case 0x5E: // dup2_x2
+ case 0x8D: // f2d
+ case 0x8B: // f2i
+ case 0x8C: // f2l
+ case 0x62: // fadd
+ case 0x30: // faload
+ case 0x51: // fastore
+ case 0x96: // fcmpg
+ case 0x95: // fcmpl
+ case 0x0B: // fconst_0
+ case 0x0C: // fconst_1
+ case 0x0D: // fconst_2
+ case 0x6E: // fdiv
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x17: // fload
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x22: // fload_0
+ case 0x23: // fload_1
+ case 0x24: // fload_2
+ case 0x25: // fload_3
+ builder.addInsn(insnIndex, 0x17, opcode - 0x22);
+ break;
+ case 0x6A: // fmul
+ case 0x76: // fneg
+ case 0x72: // frem
+ case 0xAE: // freturn
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x38: // fstore
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x43: // fstore_0
+ case 0x44: // fstore_1
+ case 0x45: // fstore_2
+ case 0x46: // fstore_3
+ builder.addInsn(insnIndex, 0x38, opcode - 0x43);
+ break;
+ case 0x66: // fsub
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xB4: // getfield
+ case 0xB2: // getstatic
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0xA7: // goto
+ builder.addInsn(
+ insnIndex, opcode, new InstructionIndex(startOffset + parser.s2(), builder));
+ bytecodeOffset += 2;
+ break;
+ case 0xC8: // goto_w
+ builder.addInsn(
+ insnIndex, 0xA7, new InstructionIndex(startOffset + parser.u4(), builder));
+ bytecodeOffset += 4;
+ break;
+ case 0x91: // i2b
+ case 0x92: // i2c
+ case 0x87: // i2d
+ case 0x86: // i2f
+ case 0x85: // i2l
+ case 0x93: // i2s
+ case 0x60: // iadd
+ case 0x2E: // iaload
+ case 0x7E: // iand
+ case 0x4F: // iastore
+ case 0x02: // iconst_m1
+ case 0x03: // iconst_0
+ case 0x04: // iconst_1
+ case 0x05: // iconst_2
+ case 0x06: // iconst_3
+ case 0x07: // iconst_4
+ case 0x08: // iconst_5
+ case 0x6C: // idiv
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xA5: // if_acmpeq
+ case 0xA6: // if_acmpne
+ case 0x9F: // if_icmpeq
+ case 0xA0: // if_icmpne
+ case 0xA1: // if_icmplt
+ case 0xA2: // if_icmpge
+ case 0xA3: // if_icmpgt
+ case 0xA4: // if_icmple
+ case 0x99: // ifeq
+ case 0x9A: // ifne
+ case 0x9B: // iflt
+ case 0x9C: // ifge
+ case 0x9D: // ifgt
+ case 0x9E: // ifle
+ case 0xC7: // ifnonnull
+ case 0xC6: // ifnull
+ builder.addInsn(
+ insnIndex, opcode, new InstructionIndex(startOffset + parser.s2(), builder));
+ bytecodeOffset += 2;
+ break;
+ case 0x84: // iinc
+ builder.addInsn(insnIndex, opcode, parser.u1(), parser.s1());
+ bytecodeOffset += 2;
+ break;
+ case 0x15: // iload
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x1A: // iload_0
+ case 0x1B: // iload_1
+ case 0x1C: // iload_2
+ case 0x1D: // iload_3
+ builder.addInsn(insnIndex, 0x15, opcode - 0x1A);
+ break;
+ case 0x68: // imul
+ case 0x74: // ineg
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xC1: // instanceof
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0xBA: // invokedynamic
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ parser.u2();
+ bytecodeOffset += 4;
+ break;
+ case 0xB9: // invokeinterface
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()), parser.u1());
+ parser.u1();
+ bytecodeOffset += 4;
+ break;
+ case 0xB7: // invokespecial
+ case 0xB8: // invokestatic
+ case 0xB6: // invokevirtual
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0x80: // ior
+ case 0x70: // irem
+ case 0xAC: // ireturn
+ case 0x78: // ishl
+ case 0x7A: // ishr
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x36: // istore
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x3B: // istore_0
+ case 0x3C: // istore_1
+ case 0x3D: // istore_2
+ case 0x3E: // istore_3
+ builder.addInsn(insnIndex, 0x36, opcode - 0x3B);
+ break;
+ case 0x64: // isub
+ case 0x7C: // iushr
+ case 0x82: // ixor
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xA8: // jsr
+ builder.addInsn(
+ insnIndex, opcode, new InstructionIndex(startOffset + parser.s2(), builder));
+ bytecodeOffset += 2;
+ break;
+ case 0xC9: // jsr_w
+ builder.addInsn(
+ insnIndex, 0xA8, new InstructionIndex(startOffset + parser.u4(), builder));
+ bytecodeOffset += 4;
+ break;
+ case 0x8A: // l2d
+ case 0x89: // l2f
+ case 0x88: // l2i
+ case 0x61: // ladd
+ case 0x2F: // laload
+ case 0x7F: // land
+ case 0x50: // lastore
+ case 0x94: // lcmp
+ case 0x09: // lconst_0
+ case 0x0A: // lconst_1
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x12: // ldc
+ builder.addInsn(insnIndex, 0x12, builder.getCpInfo(parser.u1()));
+ bytecodeOffset += 1;
+ break;
+ case 0x13: // ldc_w
+ case 0x14: // ldc2_w
+ builder.addInsn(insnIndex, opcode == 0x13 ? 0x12 : 0x14, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0x6D: // ldiv
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x16: // lload
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x1E: // lload_0
+ case 0x1F: // lload_1
+ case 0x20: // lload_2
+ case 0x21: // lload_3
+ builder.addInsn(insnIndex, 0x16, opcode - 0x1E);
+ break;
+ case 0x69: // lmul
+ case 0x75: // lneg
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xAB: // lookupswitch
+ builder.addInsn(insnIndex, opcode);
+ while (bytecodeOffset % 4 != 0) {
+ parser.u1();
+ bytecodeOffset++;
+ }
+ builder.addInsnIndex("default: ", startOffset + parser.u4());
+ int pairCount = builder.add("npairs: ", parser.u4());
+ bytecodeOffset += 8;
+ for (int i = 0; i < pairCount; ++i) {
+ builder.addInsnIndex(parser.u4() + ": ", startOffset + parser.u4());
+ bytecodeOffset += 8;
+ }
+ break;
+ case 0x81: // lor
+ case 0x71: // lrem
+ case 0xAD: // lreturn
+ case 0x79: // lshl
+ case 0x7B: // lshr
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x37: // lstore
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x3F: // lstore_0
+ case 0x40: // lstore_1
+ case 0x41: // lstore_2
+ case 0x42: // lstore_3
+ builder.addInsn(insnIndex, 0x37, opcode - 0x3F);
+ break;
+ case 0x65: // lsub
+ case 0x7D: // lushr
+ case 0x83: // lxor
+ case 0xC2: // monitorenter
+ case 0xC3: // monitorexit
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xC5: // multianewarray
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()), parser.u1());
+ bytecodeOffset += 3;
+ break;
+ case 0xBB: // new
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0xBC: // newarray
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0x00: // nop
+ case 0x57: // pop
+ case 0x58: // pop2
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xB5: // putfield
+ case 0xB3: // putstatic
+ builder.addInsn(insnIndex, opcode, builder.getCpInfo(parser.u2()));
+ bytecodeOffset += 2;
+ break;
+ case 0xA9: // ret
+ builder.addInsn(insnIndex, opcode, parser.u1());
+ bytecodeOffset += 1;
+ break;
+ case 0xB1: // return
+ case 0x35: // saload
+ case 0x56: // sastore
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0x11: // sipush
+ builder.addInsn(insnIndex, opcode, parser.s2());
+ bytecodeOffset += 2;
+ break;
+ case 0x5F: // swap
+ builder.addInsn(insnIndex, opcode);
+ break;
+ case 0xAA: // tableswitch
+ builder.addInsn(insnIndex, opcode);
+ while (bytecodeOffset % 4 != 0) {
+ parser.u1();
+ bytecodeOffset++;
+ }
+ builder.addInsnIndex("default: ", startOffset + parser.u4());
+ int low = builder.add("low: ", parser.u4());
+ int high = builder.add("high: ", parser.u4());
+ bytecodeOffset += 12;
+ for (int i = low; i <= high; ++i) {
+ builder.addInsnIndex(i + ": ", startOffset + parser.u4());
+ bytecodeOffset += 4;
+ }
+ break;
+ case 0xC4: // wide
+ opcode = parser.u1();
+ bytecodeOffset += 1;
+ switch (opcode) {
+ case 0x15: // iload
+ case 0x17: // fload
+ case 0x19: // aload
+ case 0x16: // lload
+ case 0x18: // dload
+ case 0x36: // istore
+ case 0x38: // fstore
+ case 0x3A: // astore
+ case 0x37: // lstore
+ case 0x39: // dstore
+ case 0xA9: // ret
+ builder.addInsn(insnIndex, opcode, parser.u2());
+ bytecodeOffset += 2;
+ break;
+ case 0x84: // iinc
+ builder.addInsn(insnIndex, opcode, parser.u2(), parser.s2());
+ bytecodeOffset += 4;
+ break;
+ default:
+ throw new ClassFormatException("Unknown wide opcode: " + opcode);
+ }
+ break;
+ default:
+ throw new ClassFormatException("Unknown opcode: " + opcode);
+ }
+ insnIndex++;
+ }
+ builder.putInsnIndex(bytecodeOffset, insnIndex);
+ }
+
+ /**
+ * Parses and dumps a StackMapTable attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4">JVMS
+ * 4.7.4</a>
+ */
+ private static void dumpStackMapTableAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int entryCount = builder.add("number_of_entries: ", parser.u2());
+ int bytecodeOffset = -1;
+ for (int i = 0; i < entryCount; ++i) {
+ int frameType = parser.u1();
+ if (frameType < 64) {
+ int offsetDelta = frameType;
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("SAME ", bytecodeOffset);
+ } else if (frameType < 128) {
+ int offsetDelta = frameType - 64;
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("SAME_LOCALS_1_STACK_ITEM ", bytecodeOffset);
+ dumpVerificationTypeInfo(parser, builder);
+ } else if (frameType < 247) {
+ throw new ClassFormatException("Unknown frame type " + frameType);
+ } else if (frameType == 247) {
+ int offsetDelta = parser.u2();
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("SAME_LOCALS_1_STACK_ITEM ", bytecodeOffset);
+ dumpVerificationTypeInfo(parser, builder);
+ } else if (frameType < 251) {
+ int offsetDelta = parser.u2();
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("CHOP_" + (251 - frameType) + " ", bytecodeOffset);
+ } else if (frameType == 251) {
+ int offsetDelta = parser.u2();
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("SAME ", bytecodeOffset);
+ } else if (frameType < 255) {
+ int offsetDelta = parser.u2();
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("APPEND_" + (frameType - 251) + " ", bytecodeOffset);
+ for (int j = 0; j < frameType - 251; ++j) {
+ dumpVerificationTypeInfo(parser, builder);
+ }
+ } else {
+ int offsetDelta = parser.u2();
+ bytecodeOffset += offsetDelta + 1;
+ builder.addInsnIndex("FULL ", bytecodeOffset);
+ int numberOfLocals = builder.add("number_of_locals: ", parser.u2());
+ for (int j = 0; j < numberOfLocals; ++j) {
+ dumpVerificationTypeInfo(parser, builder);
+ }
+ int numberOfStackItems = builder.add("number_of_stack_items: ", parser.u2());
+ for (int j = 0; j < numberOfStackItems; ++j) {
+ dumpVerificationTypeInfo(parser, builder);
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses and dumps a verification_type_info structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.2">JVMS
+ * 4.7.2</a>
+ */
+ private static void dumpVerificationTypeInfo(final Parser parser, final Builder builder)
+ throws IOException {
+ int tag = builder.add("tag: ", parser.u1());
+ if (tag > 8) {
+ throw new ClassFormatException("Unknown verification_type_info tag: " + tag);
+ }
+ if (tag == 7) {
+ builder.addCpInfo("cpool_index: ", parser.u2());
+ } else if (tag == 8) {
+ builder.addInsnIndex("offset: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps an Exception attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.5">JVMS
+ * 4.7.5</a>
+ */
+ private static void dumpExceptionsAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int exceptionCount = builder.add("number_of_exceptions: ", parser.u2());
+ for (int i = 0; i < exceptionCount; ++i) {
+ builder.addCpInfo("exception_index: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps an InnerClasses attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.6">JVMS
+ * 4.7.6</a>
+ */
+ private static void dumpInnerClassesAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int classCount = builder.add("number_of_classes: ", parser.u2());
+ for (int i = 0; i < classCount; ++i) {
+ builder.addCpInfo("inner_class_info_index: ", parser.u2());
+ builder.addCpInfo("outer_class_info_index: ", parser.u2());
+ builder.addCpInfo("inner_name_index: ", parser.u2());
+ builder.add("inner_class_access_flags: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps an EnclosingMethod attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.7">JVMS
+ * 4.7.7</a>
+ */
+ private static void dumpEnclosingMethodAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("class_index: ", parser.u2());
+ builder.addCpInfo("method_index: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a Synthetic attribute.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.8">JVMS
+ * 4.7.8</a>
+ */
+ private static void dumpSyntheticAttribute() {
+ // Nothing to parse.
+ }
+
+ /**
+ * Parses and dumps a Signature attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9">JVMS
+ * 4.7.9</a>
+ */
+ private static void dumpSignatureAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("signature_index: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a SourceFile attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.10">JVMS
+ * 4.7.10</a>
+ */
+ private static void dumpSourceFileAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("sourcefile_index: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a SourceDebug attribute.
+ *
+ * @param attributeLength the length of the SourceDebug attribute (excluding its 6 header bytes).
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.11">JVMS
+ * 4.7.11</a>
+ */
+ private static void dumpSourceDebugAttribute(
+ final int attributeLength, final Parser parser, final Builder builder) throws IOException {
+ byte[] attributeData = parser.bytes(attributeLength);
+ StringBuilder stringBuilder = new StringBuilder();
+ for (byte data : attributeData) {
+ stringBuilder.append(data).append(',');
+ }
+ builder.add("debug_extension: ", stringBuilder.toString());
+ }
+
+ /**
+ * Parses and dumps a LineNumberTable attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.12">JVMS
+ * 4.7.12</a>
+ */
+ private static void dumpLineNumberTableAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int lineNumberCount = builder.add("line_number_table_length: ", parser.u2());
+ for (int i = 0; i < lineNumberCount; ++i) {
+ builder.addInsnIndex("start_pc: ", parser.u2());
+ builder.add("line_number: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a LocalVariableTable attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.13">JVMS
+ * 4.7.13</a>
+ */
+ private static void dumpLocalVariableTableAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int localVariableCount = builder.add("local_variable_table_length: ", parser.u2());
+ for (int i = 0; i < localVariableCount; ++i) {
+ int startPc = builder.addInsnIndex("start_pc: ", parser.u2());
+ builder.addInsnIndex("length: ", startPc + parser.u2());
+ builder.addCpInfo("name_index: ", parser.u2());
+ builder.addCpInfo("descriptor_index: ", parser.u2());
+ builder.add("index: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a LocalVariableTypeTable attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.14">JVMS
+ * 4.7.14</a>
+ */
+ private static void dumpLocalVariableTypeTableAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ int localVariableCount = builder.add("local_variable_type_table_length: ", parser.u2());
+ for (int i = 0; i < localVariableCount; ++i) {
+ int startPc = builder.addInsnIndex("start_pc: ", parser.u2());
+ builder.addInsnIndex("length: ", startPc + parser.u2());
+ builder.addCpInfo("name_index: ", parser.u2());
+ builder.addCpInfo("signature_index: ", parser.u2());
+ builder.add("index: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a Deprecated attribute.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.15">JVMS
+ * 4.7.15</a>
+ */
+ private static void dumpDeprecatedAttribute() {
+ // Nothing to parse.
+ }
+
+ /**
+ * Parses and dumps a RuntimeVisibleAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16">JVMS
+ * 4.7.16</a>
+ */
+ private static void dumpRuntimeVisibleAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ int annotationCount = builder.add("num_annotations: ", parser.u2());
+ for (int i = 0; i < annotationCount; ++i) {
+ dumpAnnotation(parser, builder);
+ }
+ }
+
+ /**
+ * Parses and dumps an annotations structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16">JVMS
+ * 4.7.16</a>
+ */
+ private static void dumpAnnotation(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("type_index: ", parser.u2());
+ int elementValuePairCount = builder.add("num_element_value_pairs: ", parser.u2());
+ for (int i = 0; i < elementValuePairCount; ++i) {
+ builder.addCpInfo("element_name_index: ", parser.u2());
+ dumpElementValue(parser, builder);
+ }
+ }
+
+ /**
+ * Parses and dumps an element_value structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1">JVMS
+ * 4.7.16.1</a>
+ */
+ private static void dumpElementValue(final Parser parser, final Builder builder)
+ throws IOException {
+ int tag = parser.u1();
+ switch (tag) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ case 's':
+ builder.addCpInfo(((char) tag) + ": ", parser.u2());
+ return;
+ case 'e':
+ builder.addCpInfo("e: ", parser.u2());
+ builder.addCpInfo("const_name_index: ", parser.u2());
+ return;
+ case 'c':
+ builder.addCpInfo(((char) tag) + ": ", parser.u2());
+ return;
+ case '@':
+ builder.add("@: ", "");
+ dumpAnnotation(parser, builder);
+ return;
+ case '[':
+ int valueCount = builder.add("[: ", parser.u2());
+ for (int i = 0; i < valueCount; ++i) {
+ dumpElementValue(parser, builder);
+ }
+ return;
+ default:
+ throw new ClassFormatException("Unknown element_type tag: " + tag);
+ }
+ }
+
+ /**
+ * Parses and dumps a RuntimeInvisibleAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.17">JVMS
+ * 4.7.17</a>
+ */
+ private static void dumpRuntimeInvisibleAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ dumpRuntimeVisibleAnnotationsAttribute(parser, builder);
+ }
+
+ /**
+ * Parses and dumps a RuntimeVisibleParameterAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18">JVMS
+ * 4.7.18</a>
+ */
+ private static void dumpRuntimeVisibleParameterAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ int parameterCount = builder.add("num_parameters: ", parser.u1());
+ for (int i = 0; i < parameterCount; ++i) {
+ int annotationCount = builder.add("num_annotations: ", parser.u2());
+ for (int j = 0; j < annotationCount; ++j) {
+ dumpAnnotation(parser, builder);
+ }
+ }
+ }
+
+ /**
+ * Parses and dumps a RuntimeInvisibleParameterAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.19">JVMS
+ * 4.7.19</a>
+ */
+ private static void dumpRuntimeInvisibleParameterAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ dumpRuntimeVisibleParameterAnnotationsAttribute(parser, builder);
+ }
+
+ /**
+ * Parses and dumps a RuntimeVisibleTypeAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20">JVMS
+ * 4.7.20</a>
+ */
+ private static void dumpRuntimeVisibleTypeAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ int annotationCount = builder.add("num_annotations: ", parser.u2());
+ SortedBuilder sortedBuilder = builder.addSortedBuilder();
+ for (int i = 0; i < annotationCount; ++i) {
+ dumpTypeAnnotation(parser, sortedBuilder);
+ }
+ }
+
+ /**
+ * Parses and dumps a type_annotation structure.
+ *
+ * @param parser a class parser.
+ * @param sortedBuilder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20">JVMS
+ * 4.7.20</a>
+ */
+ private static void dumpTypeAnnotation(final Parser parser, final SortedBuilder sortedBuilder)
+ throws IOException {
+ int targetType = parser.u1();
+ Builder builder = sortedBuilder.addBuilder(String.valueOf(targetType));
+ builder.add("target_type: ", targetType);
+ switch (targetType) {
+ case 0x00:
+ case 0x01:
+ // type_parameter_target
+ builder.add("type_parameter_index: ", parser.u1());
+ break;
+ case 0x10:
+ // supertype_target
+ builder.add("supertype_index: ", parser.u2());
+ break;
+ case 0x11:
+ case 0x12:
+ // type_parameter_bound_target
+ builder.add("type_parameter_index: ", parser.u1());
+ builder.add("bound_index: ", parser.u1());
+ break;
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ // empty_target
+ // Nothing to parse.
+ break;
+ case 0x16:
+ // formal_parameter_target
+ builder.add("formal_parameter_index: ", parser.u1());
+ break;
+ case 0x17:
+ // throws_target
+ builder.add("throws_type_index: ", parser.u2());
+ break;
+ case 0x40:
+ case 0x41:
+ // localvar_target
+ int tableLength = builder.add("table_length: ", parser.u2());
+ for (int i = 0; i < tableLength; ++i) {
+ int startPc = builder.addInsnIndex("start_pc: ", parser.u2());
+ builder.addInsnIndex("length: ", startPc + parser.u2());
+ builder.add("index: ", parser.u2());
+ }
+ break;
+ case 0x42:
+ // catch_target
+ builder.add("exception_table_index: ", parser.u2());
+ break;
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ // offset_target
+ builder.addInsnIndex("offset: ", parser.u2());
+ break;
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4A:
+ case 0x4B:
+ // type_argument_target
+ builder.addInsnIndex("offset: ", parser.u2());
+ builder.add("type_argument_index: ", parser.u1());
+ break;
+ default:
+ throw new ClassFormatException("Unknown target_type: " + targetType);
+ }
+ dumpTypePath(parser, builder);
+ // Sort type annotations based on the full target_info and type_path (excluding the annotation
+ // content), instead of only on their target_type.
+ builder.sortByContent();
+ dumpAnnotation(parser, builder);
+ }
+
+ /**
+ * Parses and dumps a type_path structure.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.2">JVMS
+ * 4.7.20.2</a>
+ */
+ private static void dumpTypePath(final Parser parser, final Builder builder) throws IOException {
+ int pathLength = builder.add("path_length: ", parser.u1());
+ for (int i = 0; i < pathLength; ++i) {
+ builder.add("type_path_kind: ", parser.u1());
+ builder.add("type_argument_index: ", parser.u1());
+ }
+ }
+
+ /**
+ * Parses and dumps a RuntimeInvisibleTypeAnnotations attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.21">JVMS
+ * 4.7.21</a>
+ */
+ private static void dumpRuntimeInvisibleTypeAnnotationsAttribute(
+ final Parser parser, final Builder builder) throws IOException {
+ dumpRuntimeVisibleTypeAnnotationsAttribute(parser, builder);
+ }
+
+ /**
+ * Parses and dumps an AnnotationDefault attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.22">JVMS
+ * 4.7.22</a>
+ */
+ private static void dumpAnnotationDefaultAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ dumpElementValue(parser, builder);
+ }
+
+ /**
+ * Parses and dumps a BootstrapMethods attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23">JVMS
+ * 4.7.23</a>
+ */
+ private static void dumpBootstrapMethodsAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int bootstrapMethodCount = builder.add("num_bootstrap_methods: ", parser.u2());
+ for (int i = 0; i < bootstrapMethodCount; ++i) {
+ builder.addCpInfo("bootstrap_method_ref: ", parser.u2());
+ int bootstrapArgumentCount = builder.add("num_bootstrap_arguments: ", parser.u2());
+ for (int j = 0; j < bootstrapArgumentCount; ++j) {
+ builder.addCpInfo("bootstrap_argument: ", parser.u2());
+ }
+ }
+ }
+
+ /**
+ * Parses and dumps a MethodParameters attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.24">JVMS
+ * 4.7.24</a>
+ */
+ private static void dumpMethodParametersAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int parameterCount = builder.add("parameters_count: ", parser.u1());
+ for (int i = 0; i < parameterCount; ++i) {
+ builder.addCpInfo("name_index: ", parser.u2());
+ builder.add("access_flags: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a Module attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.25">JVMS
+ * 4.7.25</a>
+ */
+ private static void dumpModuleAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("name: ", parser.u2());
+ builder.add("access: ", parser.u2());
+ builder.addCpInfo("version: ", parser.u2());
+ int requireCount = builder.add("require_count: ", parser.u2());
+ for (int i = 0; i < requireCount; ++i) {
+ builder.addCpInfo("name: ", parser.u2());
+ builder.add("access: ", parser.u2());
+ builder.addCpInfo("version: ", parser.u2());
+ }
+ int exportCount = builder.add("export_count: ", parser.u2());
+ for (int i = 0; i < exportCount; ++i) {
+ builder.addCpInfo("name: ", parser.u2());
+ builder.add("access: ", parser.u2());
+ int exportToCount = builder.add("export_to_count: ", parser.u2());
+ for (int j = 0; j < exportToCount; ++j) {
+ builder.addCpInfo("to: ", parser.u2());
+ }
+ }
+ int openCount = builder.add("open_count: ", parser.u2());
+ for (int i = 0; i < openCount; ++i) {
+ builder.addCpInfo("name: ", parser.u2());
+ builder.add("access: ", parser.u2());
+ int openToCount = builder.add("open_to_count: ", parser.u2());
+ for (int j = 0; j < openToCount; ++j) {
+ builder.addCpInfo("to: ", parser.u2());
+ }
+ }
+ int useCount = builder.add("use_count: ", parser.u2());
+ for (int i = 0; i < useCount; ++i) {
+ builder.addCpInfo("use: ", parser.u2());
+ }
+ int provideCount = builder.add("provide_count: ", parser.u2());
+ for (int i = 0; i < provideCount; ++i) {
+ builder.addCpInfo("provide: ", parser.u2());
+ int provideWithCount = builder.add("provide_with_count: ", parser.u2());
+ for (int j = 0; j < provideWithCount; ++j) {
+ builder.addCpInfo("with: ", parser.u2());
+ }
+ }
+ }
+
+ /**
+ * Parses and dumps a ModulePackages attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.26">JVMS
+ * 4.7.26</a>
+ */
+ private static void dumpModulePackagesAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int packageCount = builder.add("package_count: ", parser.u2());
+ for (int i = 0; i < packageCount; ++i) {
+ builder.addCpInfo("package: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a ModuleMainClass attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.27">JVMS
+ * 4.7.27</a>
+ */
+ private static void dumpModuleMainClassAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("main_class: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a NestHost attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.28">JVMS
+ * 4.7.28</a>
+ */
+ private static void dumpNestHostAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ builder.addCpInfo("host_class: ", parser.u2());
+ }
+
+ /**
+ * Parses and dumps a NestMembers attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.29">JVMS
+ * 4.7.29</a>
+ */
+ private static void dumpNestMembersAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int numberOfClasses = builder.add("number_of_classes: ", parser.u2());
+ for (int i = 0; i < numberOfClasses; ++i) {
+ builder.addCpInfo("class: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a PermittedSubclasses attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://openjdk.java.net/jeps/360">JEP 360</a>
+ */
+ private static void dumpPermittedSubclassesAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int permittedSubclassesCount = builder.add("permitted_subclasses_count: ", parser.u2());
+ for (int i = 0; i < permittedSubclassesCount; ++i) {
+ builder.addCpInfo("class: ", parser.u2());
+ }
+ }
+
+ /**
+ * Parses and dumps a Record attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a href="https://openjdk.java.net/jeps/360">JEP 360</a>
+ */
+ private static void dumpRecordAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int numberOfComponentRecords = builder.add("number_of_component_records: ", parser.u2());
+ for (int i = 0; i < numberOfComponentRecords; ++i) {
+ builder.addCpInfo("record_component_name: ", parser.u2());
+ builder.addCpInfo("record_component_descriptor: ", parser.u2());
+ dumpAttributeList(parser, builder);
+ }
+ }
+
+ /**
+ * Parses and dumps a StackMap attribute.
+ *
+ * @param parser a class parser.
+ * @param builder a dump builder.
+ * @throws IOException if the class can't be parsed.
+ * @see <a
+ * href="http://docs.oracle.com/javame/config/cldc/opt-pkgs/api/cldc/api/Appendix1-verifier.pdf">CLDC</a>
+ */
+ private static void dumpStackMapAttribute(final Parser parser, final Builder builder)
+ throws IOException {
+ int entryCount = builder.add("number_of_entries: ", parser.u2());
+ for (int i = 0; i < entryCount; ++i) {
+ builder.addInsnIndex("offset: ", parser.u2());
+ int numberOfLocals = builder.add("number_of_locals: ", parser.u2());
+ for (int j = 0; j < numberOfLocals; ++j) {
+ dumpVerificationTypeInfo(parser, builder);
+ }
+ int numberOfStackItems = builder.add("number_of_stack_items: ", parser.u2());
+ for (int j = 0; j < numberOfStackItems; ++j) {
+ dumpVerificationTypeInfo(parser, builder);
+ }
+ }
+ }
+
+ /** An abstract constant pool item. */
+ private abstract static class CpInfo {
+ /** The dump of this item. */
+ private String dump;
+ /** The context to use to get the referenced constant pool items. */
+ private final ClassContext classContext;
+
+ /**
+ * Constructs a CpInfo for an item without references to other items.
+ *
+ * @param dump the dump of this item.
+ */
+ CpInfo(final String dump) {
+ this.dump = dump;
+ this.classContext = null;
+ }
+
+ /**
+ * Constructs a CpInfo for an item with references to other items.
+ *
+ * @param classContext a context to lookup constant pool items from their index.
+ */
+ CpInfo(final ClassContext classContext) {
+ this.classContext = classContext;
+ }
+
+ /**
+ * Returns the number of entries used by this item in constant_pool.
+ *
+ * @return the number of entries used by this item in constant_pool.
+ */
+ int size() {
+ return 1;
+ }
+
+ /**
+ * Returns the constant pool item with the given index.
+ *
+ * @param <C> a CpInfo subclass.
+ * @param cpIndex a constant pool entry index.
+ * @param cpInfoType the expected type of the constant pool entry.
+ * @return the constant pool item with the given index.
+ */
+ <C extends CpInfo> C getCpInfo(final int cpIndex, final Class<C> cpInfoType) {
+ return classContext.getCpInfo(cpIndex, cpInfoType);
+ }
+
+ /**
+ * Returns the dump of this item.
+ *
+ * @return the dump of this item.
+ */
+ String dump() {
+ return dump;
+ }
+
+ @Override
+ public String toString() {
+ if (dump == null) {
+ dump = getClass().getSimpleName() + " " + dump();
+ }
+ return dump;
+ }
+ }
+
+ /**
+ * A CONSTANT_Class_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.1">JVMS
+ * 4.4.1</a>
+ */
+ private static class ConstantClassInfo extends CpInfo {
+ private final int nameIndex;
+
+ /**
+ * Parses a CONSTANT_Class_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantClassInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.nameIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(nameIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Fieldref_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.2">JVMS
+ * 4.4.2</a>
+ */
+ private static class ConstantFieldRefInfo extends CpInfo {
+ private final int classIndex;
+ private final int nameAndTypeIndex;
+
+ /**
+ * Parses a CONSTANT_Fieldref_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantFieldRefInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.classIndex = parser.u2();
+ this.nameAndTypeIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(classIndex, ConstantClassInfo.class).dump()
+ + "."
+ + getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Methodref_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.2">JVMS
+ * 4.4.2</a>
+ */
+ private static class ConstantMethodRefInfo extends CpInfo {
+ private final int classIndex;
+ private final int nameAndTypeIndex;
+
+ /**
+ * Parses a CONSTANT_Methodref_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantMethodRefInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.classIndex = parser.u2();
+ this.nameAndTypeIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(classIndex, ConstantClassInfo.class).dump()
+ + "."
+ + getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_InterfaceMethodref_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.2">JVMS
+ * 4.4.2</a>
+ */
+ private static class ConstantInterfaceMethodRefInfo extends CpInfo {
+ private final int classIndex;
+ private final int nameAndTypeIndex;
+
+ /**
+ * Parses a CONSTANT_InterfaceMethodref_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantInterfaceMethodRefInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ super(classContext);
+ this.classIndex = parser.u2();
+ this.nameAndTypeIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(classIndex, ConstantClassInfo.class).dump()
+ + "."
+ + getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_String_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.3">JVMS
+ * 4.4.3</a>
+ */
+ private static class ConstantStringInfo extends CpInfo {
+ final int stringIndex;
+
+ /**
+ * Parses a CONSTANT_String_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantStringInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.stringIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(stringIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Integer_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.4">JVMS
+ * 4.4.4</a>
+ */
+ private static class ConstantIntegerInfo extends CpInfo {
+
+ /**
+ * Parses a CONSTANT_Integer_info item.
+ *
+ * @param parser a class parser.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantIntegerInfo(final Parser parser) throws IOException {
+ super(Integer.toString(parser.u4()));
+ }
+ }
+
+ /**
+ * A CONSTANT_Float_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.4">JVMS
+ * 4.4.4</a>
+ */
+ private static class ConstantFloatInfo extends CpInfo {
+
+ /**
+ * Parses a CONSTANT_Float_info item.
+ *
+ * @param parser a class parser.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantFloatInfo(final Parser parser) throws IOException {
+ super(Float.toString(Float.intBitsToFloat(parser.u4())));
+ }
+ }
+
+ /**
+ * A CONSTANT_Long_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.5">JVMS
+ * 4.4.5</a>
+ */
+ private static class ConstantLongInfo extends CpInfo {
+
+ /**
+ * Parses a CONSTANT_Long_info item.
+ *
+ * @param parser a class parser.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantLongInfo(final Parser parser) throws IOException {
+ super(Long.toString(parser.s8()));
+ }
+
+ @Override
+ int size() {
+ return 2;
+ }
+ }
+
+ /**
+ * A CONSTANT_Double_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.5">JVMS
+ * 4.4.5</a>
+ */
+ private static class ConstantDoubleInfo extends CpInfo {
+
+ /**
+ * Parses a CONSTANT_Double_info item.
+ *
+ * @param parser a class parser.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantDoubleInfo(final Parser parser) throws IOException {
+ super(Double.toString(Double.longBitsToDouble(parser.s8())));
+ }
+
+ @Override
+ int size() {
+ return 2;
+ }
+ }
+
+ /**
+ * A CONSTANT_NameAndType_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.6">JVMS
+ * 4.4.6</a>
+ */
+ private static class ConstantNameAndTypeInfo extends CpInfo {
+ private final int nameIndex;
+ private final int descriptorIndex;
+
+ /**
+ * Parses a CONSTANT_NameAndType_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantNameAndTypeInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ super(classContext);
+ this.nameIndex = parser.u2();
+ this.descriptorIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(nameIndex, ConstantUtf8Info.class).dump()
+ + getCpInfo(descriptorIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Utf8_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.7">JVMS
+ * 4.4.7</a>
+ */
+ private static class ConstantUtf8Info extends CpInfo {
+
+ /**
+ * Parses a CONSTANT_Utf8_info item.
+ *
+ * @param parser a class parser.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantUtf8Info(final Parser parser) throws IOException {
+ super(parser.utf8());
+ }
+ }
+
+ /**
+ * A CONSTANT_MethodHandle_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8">JVMS
+ * 4.4.8</a>
+ */
+ private static class ConstantMethodHandleInfo extends CpInfo {
+ private final int referenceKind;
+ private final int referenceIndex;
+
+ /**
+ * Parses a CONSTANT_MethodHandle_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantMethodHandleInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ super(classContext);
+ this.referenceKind = parser.u1();
+ this.referenceIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return referenceKind + "." + getCpInfo(referenceIndex, CpInfo.class);
+ }
+ }
+
+ /**
+ * A CONSTANT_MethodType_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.9">JVMS
+ * 4.4.9</a>
+ */
+ private static class ConstantMethodTypeInfo extends CpInfo {
+ private final int descriptorIndex;
+
+ /**
+ * Parses a CONSTANT_MethodType_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantMethodTypeInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ super(classContext);
+ this.descriptorIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(descriptorIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_InvokeDynamic_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.10">JVMS
+ * 4.4.10</a>
+ */
+ private static class ConstantInvokeDynamicInfo extends CpInfo {
+ private final int bootstrapMethodAttrIndex;
+ private final int nameAndTypeIndex;
+
+ /**
+ * Parses a CONSTANT_InvokeDynamic_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantInvokeDynamicInfo(final Parser parser, final ClassContext classContext)
+ throws IOException {
+ super(classContext);
+ this.bootstrapMethodAttrIndex = parser.u2();
+ this.nameAndTypeIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return bootstrapMethodAttrIndex
+ + "."
+ + getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Module_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.11">JVMS
+ * 4.4.11</a>
+ */
+ private static class ConstantModuleInfo extends CpInfo {
+ private final int descriptorIndex;
+
+ /**
+ * Parses a CONSTANT_Module_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantModuleInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.descriptorIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(descriptorIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Package_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.12">JVMS
+ * 4.4.12</a>
+ */
+ private static class ConstantPackageInfo extends CpInfo {
+ private final int descriptorIndex;
+
+ /**
+ * Parses a CONSTANT_Package_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantPackageInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.descriptorIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return getCpInfo(descriptorIndex, ConstantUtf8Info.class).dump();
+ }
+ }
+
+ /**
+ * A CONSTANT_Dynamic_info item.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.13">JVMS
+ * 4.4.13</a>
+ */
+ private static class ConstantDynamicInfo extends CpInfo {
+ private final int bootstrapMethodAttrIndex;
+ private final int nameAndTypeIndex;
+
+ /**
+ * Parses a CONSTANT_Dynamic_info item.
+ *
+ * @param parser a class parser.
+ * @param classContext a context to lookup constant pool items from their index.
+ * @throws IOException if the class can't be parsed.
+ */
+ ConstantDynamicInfo(final Parser parser, final ClassContext classContext) throws IOException {
+ super(classContext);
+ this.bootstrapMethodAttrIndex = parser.u2();
+ this.nameAndTypeIndex = parser.u2();
+ }
+
+ @Override
+ String dump() {
+ return bootstrapMethodAttrIndex
+ + "."
+ + getCpInfo(nameAndTypeIndex, ConstantNameAndTypeInfo.class).dump();
+ }
+ }
+
+ /**
+ * The index of a bytecode instruction. This index is computed in {@link #toString}, from the
+ * bytecode offset of the instruction, after the whole class has been parsed. Indeed, due to
+ * forward references, the index of an instruction might not be known when its offset is used.
+ *
+ * <p>Dumps use instruction indices instead of bytecode offsets in order to abstract away the low
+ * level byte code instruction representation details (e.g. an ldc vs. an ldc_w).
+ */
+ private static class InstructionIndex {
+ /** An offset in bytes from the start of the bytecode of a method. */
+ private final int bytecodeOffset;
+ /** The context to use to find the index from the bytecode offset. */
+ private final MethodContext methodContext;
+
+ InstructionIndex(final int bytecodeOffset, final MethodContext methodContext) {
+ this.bytecodeOffset = bytecodeOffset;
+ this.methodContext = methodContext;
+ }
+
+ int getBytecodeOffset() {
+ return bytecodeOffset;
+ }
+
+ @Override
+ public String toString() {
+ return "<" + methodContext.getInsnIndex(bytecodeOffset) + ">";
+ }
+ }
+
+ /**
+ * A simple byte array parser. The method names reflect the type names used in the Java Virtual
+ * Machine Specification for ease of reference.
+ */
+ private static class Parser {
+ private final DataInputStream dataInputStream;
+
+ Parser(final byte[] data) {
+ this.dataInputStream = new DataInputStream(new ByteArrayInputStream(data));
+ }
+
+ int u1() throws IOException {
+ return dataInputStream.readUnsignedByte();
+ }
+
+ int s1() throws IOException {
+ return dataInputStream.readByte();
+ }
+
+ int u2() throws IOException {
+ return dataInputStream.readUnsignedShort();
+ }
+
+ int s2() throws IOException {
+ return dataInputStream.readShort();
+ }
+
+ int u4() throws IOException {
+ return dataInputStream.readInt();
+ }
+
+ long s8() throws IOException {
+ long highBytes = dataInputStream.readInt();
+ long lowBytes = dataInputStream.readInt() & 0xFFFFFFFFL;
+ return (highBytes << 32) | lowBytes;
+ }
+
+ String utf8() throws IOException {
+ return dataInputStream.readUTF();
+ }
+
+ byte[] bytes(final int length) throws IOException {
+ if (length > dataInputStream.available()) {
+ throw new ClassFormatException("Invalid length: " + length);
+ }
+ byte[] bytes = new byte[length];
+ dataInputStream.readFully(bytes);
+ return bytes;
+ }
+ }
+
+ /** A context to lookup constant pool items from their index. */
+ private interface ClassContext {
+ <C extends CpInfo> C getCpInfo(int cpIndex, Class<C> cpInfoType);
+ }
+
+ /** A context to lookup instruction indices from their bytecode offset. */
+ private interface MethodContext {
+ int getInsnIndex(int bytecodeOffset);
+ }
+
+ /**
+ * A helper class to build the dump of a class file. The dump can't be output fully sequentially,
+ * as the input class is parsed, in particular due to the re-ordering of attributes and
+ * annotations. Instead, a tree is constructed first, then its nodes are sorted and finally the
+ * tree is parsed in Depth First Search order to build the dump. This class is the super class of
+ * the internal nodes of the tree.
+ *
+ * <p>Each internal node is a context that can store a mapping between constant pool indices and
+ * constant pool items and between bytecode offsets and instructions indices. This can be used to
+ * resolve references to such objects. Contexts inherit from their parent, i.e. if a lookup fails
+ * in some builder, the lookup continues in the parent, and so on until the root is reached.
+ */
+ private abstract static class AbstractBuilder<T> implements ClassContext, MethodContext {
+ /** Flag used to distinguish CpInfo keys in {@link #context}. */
+ private static final int CP_INFO_KEY = 0xF0000000;
+ /** The parent node of this node. May be {@literal null}. */
+ private final AbstractBuilder<?> parent;
+ /** The children of this builder. */
+ final ArrayList<T> children;
+ /** The map used to implement the Context interfaces. */
+ private final HashMap<Integer, Object> context;
+
+ AbstractBuilder(final AbstractBuilder<?> parent) {
+ this.parent = parent;
+ this.children = new ArrayList<>();
+ this.context = new HashMap<>();
+ }
+
+ /**
+ * Lookup constant pool items from their index.
+ *
+ * @param cpIndex a constant pool item index.
+ * @return the constant pool item at the given index.
+ */
+ CpInfo getCpInfo(final int cpIndex) {
+ return getCpInfo(cpIndex, CpInfo.class);
+ }
+
+ @Override
+ public <C extends CpInfo> C getCpInfo(final int cpIndex, final Class<C> cpInfoType) {
+ Object cpInfo = get(CP_INFO_KEY | cpIndex);
+ if (cpInfo == null) {
+ throw new ClassFormatException("Invalid constant pool index: " + cpIndex);
+ } else if (!cpInfoType.isInstance(cpInfo)) {
+ throw new ClassFormatException(
+ "Invalid constant pool type: "
+ + cpInfo.getClass().getName()
+ + " should be "
+ + cpInfoType.getName());
+ }
+ return cpInfoType.cast(cpInfo);
+ }
+
+ @Override
+ public int getInsnIndex(final int bytecodeOffset) {
+ Integer insnIndex = (Integer) get(bytecodeOffset);
+ if (insnIndex == null) {
+ throw new ClassFormatException("Invalid bytecode offset: " + bytecodeOffset);
+ }
+ return insnIndex;
+ }
+
+ /**
+ * Registers the CpInfo for the given constant pool index.
+ *
+ * @param cpIndex a constant pool item index.
+ * @param cpInfo a constant pool item.
+ */
+ void putCpInfo(final int cpIndex, final CpInfo cpInfo) {
+ context.put(CP_INFO_KEY | cpIndex, cpInfo);
+ }
+
+ /**
+ * Registers the instruction index for the given bytecode offset.
+ *
+ * @param bytecodeOffset a bytecode offset.
+ * @param instructionIndex the index of a bytecode instruction.
+ */
+ void putInsnIndex(final int bytecodeOffset, final int instructionIndex) {
+ context.put(bytecodeOffset, instructionIndex);
+ }
+
+ /**
+ * Recursively appends the builder's children to the given string.
+ *
+ * @param stringBuilder a string builder.
+ */
+ void build(final StringBuilder stringBuilder) {
+ for (Object child : children) {
+ if (child instanceof AbstractBuilder<?>) {
+ ((AbstractBuilder<?>) child).build(stringBuilder);
+ } else {
+ stringBuilder.append(child);
+ }
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key.
+ *
+ * @param key a context key.
+ * @return the value associated with the given key in this context or, if not found, in the
+ * parent context (recursively).
+ */
+ private Object get(final int key) {
+ Object value = context.get(key);
+ if (value != null) {
+ return value;
+ }
+ return parent == null ? null : parent.get(key);
+ }
+ }
+
+ /** An {@link AbstractBuilder} with concrete methods to add children. */
+ private static class Builder extends AbstractBuilder<Object> implements Comparable<Builder> {
+ /** The name of this builder, for sorting in {@link SortedBuilder}. */
+ private String name;
+
+ Builder(final String name, final AbstractBuilder<?> parent) {
+ super(parent);
+ this.name = name;
+ }
+
+ /**
+ * Appends name and value to children and returns value.
+ *
+ * @param <T> a value type.
+ * @param name a name.
+ * @param value a value.
+ * @return value
+ */
+ <T> T add(final String name, final T value) {
+ children.add(name);
+ children.add(value);
+ children.add("\n");
+ return value;
+ }
+
+ /**
+ * Appends name and the instruction index corresponding to bytecodeOffset to children, and
+ * returns bytecodeOffset.
+ *
+ * @param name a name.
+ * @param bytecodeOffset the offset of a bytecode instruction.
+ * @return bytecodeOffset.
+ */
+ int addInsnIndex(final String name, final int bytecodeOffset) {
+ add(name, new InstructionIndex(bytecodeOffset, this));
+ return bytecodeOffset;
+ }
+
+ /**
+ * Appends the given arguments to children.
+ *
+ * @param insnIndex the index of a bytecode instruction.
+ * @param opcode a bytecode instruction opcode.
+ * @param arguments the bytecode instruction arguments.
+ */
+ void addInsn(final int insnIndex, final int opcode, final Object... arguments) {
+ children.add(insnIndex);
+ children.add(": ");
+ children.add(opcode);
+ for (Object argument : arguments) {
+ children.add(" ");
+ children.add(argument);
+ }
+ children.add("\n");
+ }
+
+ /**
+ * Appends name and the CpInfo corresponding to cpIndex to children.
+ *
+ * @param name a name.
+ * @param cpIndex a constant pool item index.
+ */
+ void addCpInfo(final String name, final int cpIndex) {
+ add(name, cpIndex == 0 ? 0 : getCpInfo(cpIndex));
+ }
+
+ /**
+ * Appends a new {@link SortedBuilder} to children and returns it.
+ *
+ * @return a new {@link SortedBuilder}.
+ */
+ SortedBuilder addSortedBuilder() {
+ SortedBuilder sortedBuilder = new SortedBuilder(this);
+ children.add(sortedBuilder);
+ return sortedBuilder;
+ }
+
+ /** Use the content of this builder, instead of its name, to sort it in a SortedBuilder. */
+ void sortByContent() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (Object child : children) {
+ if (child instanceof InstructionIndex) {
+ // Instruction index might not be known at this point, use bytecodeOffset instead.
+ stringBuilder.append(((InstructionIndex) child).getBytecodeOffset());
+ } else {
+ stringBuilder.append(child.toString());
+ }
+ }
+ name = stringBuilder.toString();
+ }
+
+ @Override
+ public int compareTo(final Builder builder) {
+ return name.compareTo(builder.name);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ return (other instanceof Builder) && name.equals(((Builder) other).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+ }
+
+ /** An {@link AbstractBuilder} which sorts its children by name before building. */
+ private static class SortedBuilder extends AbstractBuilder<Builder> {
+ SortedBuilder(final Builder parent) {
+ super(parent);
+ }
+
+ /**
+ * Appends a new {@link Builder} to children and returns it.
+ *
+ * @param name the name of the new builder.
+ * @return the new builder.
+ */
+ Builder addBuilder(final String name) {
+ Builder builder = new Builder(name, this);
+ children.add(builder);
+ return builder;
+ }
+
+ @Override
+ void build(final StringBuilder stringBuilder) {
+ Collections.sort(children);
+ super.build(stringBuilder);
+ }
+ }
+
+ /** A simple ClassLoader to test that a class can be loaded in the JVM. */
+ private static class ByteClassLoader extends ClassLoader {
+ private final String className;
+ private final byte[] classContent;
+ private boolean classLoaded;
+
+ ByteClassLoader(final String className, final byte[] classContent) {
+ this.className = className;
+ this.classContent = classContent;
+ }
+
+ boolean classLoaded() {
+ return classLoaded;
+ }
+
+ @Override
+ protected Class<?> loadClass(final String name, final boolean resolve)
+ throws ClassNotFoundException {
+ if (name.equals(className)) {
+ classLoaded = true;
+ return defineClass(className, classContent, 0, classContent.length);
+ } else {
+ return super.loadClass(name, resolve);
+ }
+ }
+ }
+}
diff --git a/asm-test/src/main/java/org/objectweb/asm/test/ClassFormatException.java b/asm-test/src/main/java/org/objectweb/asm/test/ClassFormatException.java
new file mode 100644
index 00000000..f1aecb52
--- /dev/null
+++ b/asm-test/src/main/java/org/objectweb/asm/test/ClassFormatException.java
@@ -0,0 +1,30 @@
+package org.objectweb.asm.test;
+
+/**
+ * A {@link RuntimeException} thrown by {@link ClassFile} when a class file is malformed.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassFormatException extends RuntimeException {
+
+ private static final long serialVersionUID = -6426141818319882225L;
+
+ /**
+ * Constructs a new ClassFormatException instance.
+ *
+ * @param message the detailed message of this exception.
+ */
+ public ClassFormatException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new ClassFormatException instance.
+ *
+ * @param message the detailed message of this exception.
+ * @param cause the cause of this exception.
+ */
+ public ClassFormatException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/asm-test/src/main/java/org/objectweb/asm/test/Util.java b/asm-test/src/main/java/org/objectweb/asm/test/Util.java
new file mode 100644
index 00000000..9ea0f25d
--- /dev/null
+++ b/asm-test/src/main/java/org/objectweb/asm/test/Util.java
@@ -0,0 +1,53 @@
+package org.objectweb.asm.test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Provides utility methods for the asm.test package.
+ *
+ * @author Eric Bruneton
+ */
+final class Util {
+
+ private Util() {}
+
+ static int getMajorJavaVersion() {
+ String javaVersion = System.getProperty("java.version");
+ StringTokenizer tokenizer = new StringTokenizer(javaVersion, "._");
+ String javaMajorVersionText = tokenizer.nextToken();
+ int majorVersion = Integer.parseInt(javaMajorVersionText);
+ if (majorVersion != 1) {
+ return majorVersion;
+ }
+ javaMajorVersionText = tokenizer.nextToken();
+ return Integer.parseInt(javaMajorVersionText);
+ }
+
+ static boolean previewFeatureEnabled() {
+ try {
+ Class<?> managementFactoryClass = Class.forName("java.lang.management.ManagementFactory");
+ Method getRuntimeMxBean = managementFactoryClass.getMethod("getRuntimeMXBean");
+ Object runtimeMxBean = getRuntimeMxBean.invoke(null);
+ Class<?> runtimeMxBeanClass = Class.forName("java.lang.management.RuntimeMXBean");
+ Method getInputArguments = runtimeMxBeanClass.getMethod("getInputArguments");
+ List<?> argumentList = (List<?>) getInputArguments.invoke(runtimeMxBean);
+ return argumentList.contains("--enable-preview");
+ } catch (ClassNotFoundException e) { // JMX may be not available
+ return false;
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new AssertionError(e);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ }
+ if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+ throw new AssertionError(cause); // NOPMD
+ }
+ }
+}
diff --git a/asm-test/src/main/resources/DefaultPackage.class b/asm-test/src/main/resources/DefaultPackage.class
new file mode 100644
index 00000000..0e6cce8c
--- /dev/null
+++ b/asm-test/src/main/resources/DefaultPackage.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/ICA.class b/asm-test/src/main/resources/annotations/ICA.class
new file mode 100644
index 00000000..bb479f5b
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/ICA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/IFA.class b/asm-test/src/main/resources/annotations/IFA.class
new file mode 100644
index 00000000..c3cd37f5
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/IFA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/IMA.class b/asm-test/src/main/resources/annotations/IMA.class
new file mode 100644
index 00000000..cee7bd63
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/IMA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/IPA.class b/asm-test/src/main/resources/annotations/IPA.class
new file mode 100644
index 00000000..816a37cb
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/IPA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/ITA.class b/asm-test/src/main/resources/annotations/ITA.class
new file mode 100644
index 00000000..c05ccb2d
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/ITA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/ITPA.class b/asm-test/src/main/resources/annotations/ITPA.class
new file mode 100644
index 00000000..3734e57f
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/ITPA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/ITUA.class b/asm-test/src/main/resources/annotations/ITUA.class
new file mode 100644
index 00000000..37444036
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/ITUA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/IVA.class b/asm-test/src/main/resources/annotations/IVA.class
new file mode 100644
index 00000000..e5de15cd
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/IVA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VCA.class b/asm-test/src/main/resources/annotations/VCA.class
new file mode 100644
index 00000000..9cdf532b
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VCA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VFA.class b/asm-test/src/main/resources/annotations/VFA.class
new file mode 100644
index 00000000..59ffcf8d
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VFA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VMA.class b/asm-test/src/main/resources/annotations/VMA.class
new file mode 100644
index 00000000..82c909be
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VMA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VPA.class b/asm-test/src/main/resources/annotations/VPA.class
new file mode 100644
index 00000000..d9e6e5ba
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VPA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VTA.class b/asm-test/src/main/resources/annotations/VTA.class
new file mode 100644
index 00000000..84c0a957
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VTA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VTPA.class b/asm-test/src/main/resources/annotations/VTPA.class
new file mode 100644
index 00000000..2d0b3b92
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VTPA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VTUA.class b/asm-test/src/main/resources/annotations/VTUA.class
new file mode 100644
index 00000000..d532458a
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VTUA.class
Binary files differ
diff --git a/asm-test/src/main/resources/annotations/VVA.class b/asm-test/src/main/resources/annotations/VVA.class
new file mode 100644
index 00000000..378a3e73
--- /dev/null
+++ b/asm-test/src/main/resources/annotations/VVA.class
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidBytecodeOffset.clazz b/asm-test/src/main/resources/invalid/InvalidBytecodeOffset.clazz
new file mode 100644
index 00000000..bc5286cc
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidBytecodeOffset.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidClassVersion.clazz b/asm-test/src/main/resources/invalid/InvalidClassVersion.clazz
new file mode 100644
index 00000000..1ef8a0b1
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidClassVersion.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidCodeLength.clazz b/asm-test/src/main/resources/invalid/InvalidCodeLength.clazz
new file mode 100644
index 00000000..8378e4f4
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidCodeLength.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidConstantPoolIndex.clazz b/asm-test/src/main/resources/invalid/InvalidConstantPoolIndex.clazz
new file mode 100644
index 00000000..52360e85
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidConstantPoolIndex.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidConstantPoolReference.clazz b/asm-test/src/main/resources/invalid/InvalidConstantPoolReference.clazz
new file mode 100644
index 00000000..f0a7874f
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidConstantPoolReference.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidCpInfoTag.clazz b/asm-test/src/main/resources/invalid/InvalidCpInfoTag.clazz
new file mode 100644
index 00000000..650e8ac1
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidCpInfoTag.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidElementValue.clazz b/asm-test/src/main/resources/invalid/InvalidElementValue.clazz
new file mode 100644
index 00000000..c6cf72e0
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidElementValue.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidInsnTypeAnnotationTargetType.clazz b/asm-test/src/main/resources/invalid/InvalidInsnTypeAnnotationTargetType.clazz
new file mode 100644
index 00000000..5cbb5ac5
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidInsnTypeAnnotationTargetType.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidOpcode.clazz b/asm-test/src/main/resources/invalid/InvalidOpcode.clazz
new file mode 100644
index 00000000..3c94fceb
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidOpcode.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidSourceDebugExtension.clazz b/asm-test/src/main/resources/invalid/InvalidSourceDebugExtension.clazz
new file mode 100644
index 00000000..f7df0e82
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidSourceDebugExtension.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidStackMapFrameType.clazz b/asm-test/src/main/resources/invalid/InvalidStackMapFrameType.clazz
new file mode 100644
index 00000000..3adc7b76
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidStackMapFrameType.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidTypeAnnotationTargetType.clazz b/asm-test/src/main/resources/invalid/InvalidTypeAnnotationTargetType.clazz
new file mode 100644
index 00000000..8859aa38
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidTypeAnnotationTargetType.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidVerificationTypeInfo.clazz b/asm-test/src/main/resources/invalid/InvalidVerificationTypeInfo.clazz
new file mode 100644
index 00000000..bea541c0
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidVerificationTypeInfo.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/invalid/InvalidWideOpcode.clazz b/asm-test/src/main/resources/invalid/InvalidWideOpcode.clazz
new file mode 100644
index 00000000..59d01081
--- /dev/null
+++ b/asm-test/src/main/resources/invalid/InvalidWideOpcode.clazz
Binary files differ
diff --git a/asm-test/src/main/resources/jdk11/AllInstructions.class b/asm-test/src/main/resources/jdk11/AllInstructions.class
new file mode 100644
index 00000000..69aa4447
--- /dev/null
+++ b/asm-test/src/main/resources/jdk11/AllInstructions.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk11/AllStructures$Nested.class b/asm-test/src/main/resources/jdk11/AllStructures$Nested.class
new file mode 100644
index 00000000..9d31e7be
--- /dev/null
+++ b/asm-test/src/main/resources/jdk11/AllStructures$Nested.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk11/AllStructures.class b/asm-test/src/main/resources/jdk11/AllStructures.class
new file mode 100644
index 00000000..3aa1138b
--- /dev/null
+++ b/asm-test/src/main/resources/jdk11/AllStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk14/AllStructures$EmptyRecord.class b/asm-test/src/main/resources/jdk14/AllStructures$EmptyRecord.class
new file mode 100644
index 00000000..e2f8cb3c
--- /dev/null
+++ b/asm-test/src/main/resources/jdk14/AllStructures$EmptyRecord.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class b/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class
new file mode 100644
index 00000000..61d0a180
--- /dev/null
+++ b/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk15/AllStructures.class b/asm-test/src/main/resources/jdk15/AllStructures.class
new file mode 100644
index 00000000..851fc92f
--- /dev/null
+++ b/asm-test/src/main/resources/jdk15/AllStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/AllInstructions.class b/asm-test/src/main/resources/jdk3/AllInstructions.class
new file mode 100755
index 00000000..283d41a0
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/AllInstructions.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/AllStructures$1.class b/asm-test/src/main/resources/jdk3/AllStructures$1.class
new file mode 100755
index 00000000..c21668ed
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/AllStructures$1.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/AllStructures$InnerClass.class b/asm-test/src/main/resources/jdk3/AllStructures$InnerClass.class
new file mode 100755
index 00000000..930cad32
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/AllStructures$InnerClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/AllStructures.class b/asm-test/src/main/resources/jdk3/AllStructures.class
new file mode 100755
index 00000000..c5b7ba2c
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/AllStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/ArtificialStructures.class b/asm-test/src/main/resources/jdk3/ArtificialStructures.class
new file mode 100644
index 00000000..0ba4240b
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/ArtificialStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/LargeMethod.class b/asm-test/src/main/resources/jdk3/LargeMethod.class
new file mode 100755
index 00000000..d2547710
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/LargeMethod.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk3/SubOptimalMaxStackAndLocals.class b/asm-test/src/main/resources/jdk3/SubOptimalMaxStackAndLocals.class
new file mode 100644
index 00000000..b494edc3
--- /dev/null
+++ b/asm-test/src/main/resources/jdk3/SubOptimalMaxStackAndLocals.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllInstructions.class b/asm-test/src/main/resources/jdk5/AllInstructions.class
new file mode 100755
index 00000000..f3d08c37
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllInstructions.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures$1LocalClass.class b/asm-test/src/main/resources/jdk5/AllStructures$1LocalClass.class
new file mode 100755
index 00000000..b6ac40da
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures$1LocalClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures$EnumClass.class b/asm-test/src/main/resources/jdk5/AllStructures$EnumClass.class
new file mode 100755
index 00000000..23540f19
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures$EnumClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures$GenericInnerClass.class b/asm-test/src/main/resources/jdk5/AllStructures$GenericInnerClass.class
new file mode 100755
index 00000000..5291fe78
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures$GenericInnerClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures$InnerClass.class b/asm-test/src/main/resources/jdk5/AllStructures$InnerClass.class
new file mode 100755
index 00000000..baeb6c4a
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures$InnerClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures$InvisibleAnnotation.class b/asm-test/src/main/resources/jdk5/AllStructures$InvisibleAnnotation.class
new file mode 100755
index 00000000..485df516
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures$InvisibleAnnotation.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk5/AllStructures.class b/asm-test/src/main/resources/jdk5/AllStructures.class
new file mode 100755
index 00000000..a7de553e
--- /dev/null
+++ b/asm-test/src/main/resources/jdk5/AllStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/AllFrames.class b/asm-test/src/main/resources/jdk8/AllFrames.class
new file mode 100644
index 00000000..90d79b8c
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/AllFrames.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/AllInstructions.class b/asm-test/src/main/resources/jdk8/AllInstructions.class
new file mode 100644
index 00000000..ecd224fb
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/AllInstructions.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/AllStructures$1.class b/asm-test/src/main/resources/jdk8/AllStructures$1.class
new file mode 100644
index 00000000..24a5d7e5
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/AllStructures$1.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/AllStructures$InnerClass.class b/asm-test/src/main/resources/jdk8/AllStructures$InnerClass.class
new file mode 100644
index 00000000..2e05aa5d
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/AllStructures$InnerClass.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/AllStructures.class b/asm-test/src/main/resources/jdk8/AllStructures.class
new file mode 100644
index 00000000..3069f601
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/AllStructures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/Artificial$()$Structures.class b/asm-test/src/main/resources/jdk8/Artificial$()$Structures.class
new file mode 100644
index 00000000..1cc843ec
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/Artificial$()$Structures.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk8/LargeMethod.class b/asm-test/src/main/resources/jdk8/LargeMethod.class
new file mode 100644
index 00000000..bace5c0c
--- /dev/null
+++ b/asm-test/src/main/resources/jdk8/LargeMethod.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk9/module-info.class b/asm-test/src/main/resources/jdk9/module-info.class
new file mode 100644
index 00000000..e7418e67
--- /dev/null
+++ b/asm-test/src/main/resources/jdk9/module-info.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk9/pkg/A.class b/asm-test/src/main/resources/jdk9/pkg/A.class
new file mode 100644
index 00000000..d33ea1d3
--- /dev/null
+++ b/asm-test/src/main/resources/jdk9/pkg/A.class
Binary files differ
diff --git a/asm-test/src/main/resources/jdk9/pkg/internal/AImpl.class b/asm-test/src/main/resources/jdk9/pkg/internal/AImpl.class
new file mode 100644
index 00000000..51a374f6
--- /dev/null
+++ b/asm-test/src/main/resources/jdk9/pkg/internal/AImpl.class
Binary files differ
diff --git a/asm-test/src/resources/java/DefaultPackage.java b/asm-test/src/resources/java/DefaultPackage.java
new file mode 100644
index 00000000..d4743ee2
--- /dev/null
+++ b/asm-test/src/resources/java/DefaultPackage.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+/** Dummy interface used to test ASM with classes in the default package. */
+interface DefaultPackage {}
diff --git a/asm-test/src/resources/java/annotations/ICA.java b/asm-test/src/resources/java/annotations/ICA.java
new file mode 100644
index 00000000..c3707e74
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/ICA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible constructor annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.CONSTRUCTOR})
+public @interface ICA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/IFA.java b/asm-test/src/resources/java/annotations/IFA.java
new file mode 100644
index 00000000..d96d2008
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/IFA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible field annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.FIELD})
+public @interface IFA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/IMA.java b/asm-test/src/resources/java/annotations/IMA.java
new file mode 100644
index 00000000..fa5ea101
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/IMA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible method annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface IMA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/IPA.java b/asm-test/src/resources/java/annotations/IPA.java
new file mode 100644
index 00000000..0c9272a1
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/IPA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible parameter annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.PARAMETER})
+public @interface IPA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/IRCA.java b/asm-test/src/resources/java/annotations/IRCA.java
new file mode 100644
index 00000000..294c40b3
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/IRCA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible record component annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.RECORD_COMPONENT})
+public @interface IRCA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/ITA.java b/asm-test/src/resources/java/annotations/ITA.java
new file mode 100644
index 00000000..3202f786
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/ITA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible type annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface ITA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/ITPA.java b/asm-test/src/resources/java/annotations/ITPA.java
new file mode 100644
index 00000000..f1342150
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/ITPA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible type parameter annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE_PARAMETER})
+public @interface ITPA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/ITUA.java b/asm-test/src/resources/java/annotations/ITUA.java
new file mode 100644
index 00000000..39d1349a
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/ITUA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible type use annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE_USE})
+public @interface ITUA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/IVA.java b/asm-test/src/resources/java/annotations/IVA.java
new file mode 100644
index 00000000..50cc7f71
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/IVA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** An invisible (local) variable annotation. */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.LOCAL_VARIABLE})
+public @interface IVA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VCA.java b/asm-test/src/resources/java/annotations/VCA.java
new file mode 100644
index 00000000..c5e90efd
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VCA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible constructor annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.CONSTRUCTOR})
+public @interface VCA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VFA.java b/asm-test/src/resources/java/annotations/VFA.java
new file mode 100644
index 00000000..e5b70aea
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VFA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible field annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface VFA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VMA.java b/asm-test/src/resources/java/annotations/VMA.java
new file mode 100644
index 00000000..13f0d8e0
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VMA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible method annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface VMA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VPA.java b/asm-test/src/resources/java/annotations/VPA.java
new file mode 100644
index 00000000..42b3da64
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VPA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible parameter annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface VPA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VRCA.java b/asm-test/src/resources/java/annotations/VRCA.java
new file mode 100644
index 00000000..8d3c4362
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VRCA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible record component annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.RECORD_COMPONENT})
+public @interface VRCA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VTA.java b/asm-test/src/resources/java/annotations/VTA.java
new file mode 100644
index 00000000..d76b7b58
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VTA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible type annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface VTA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VTPA.java b/asm-test/src/resources/java/annotations/VTPA.java
new file mode 100644
index 00000000..e1561ea0
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VTPA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible type parameter annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_PARAMETER})
+public @interface VTPA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VTUA.java b/asm-test/src/resources/java/annotations/VTUA.java
new file mode 100644
index 00000000..32bde054
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VTUA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible type use annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE})
+public @interface VTUA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/annotations/VVA.java b/asm-test/src/resources/java/annotations/VVA.java
new file mode 100644
index 00000000..c5627582
--- /dev/null
+++ b/asm-test/src/resources/java/annotations/VVA.java
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** A visible (local) variable annotation. */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.LOCAL_VARIABLE})
+public @interface VVA {
+ int v();
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidBytecodeOffset.java b/asm-test/src/resources/java/invalid/InvalidBytecodeOffset.java
new file mode 100644
index 00000000..b6777c51
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidBytecodeOffset.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidBytecodeOffset {
+
+ public final int f;
+
+ public InvalidBytecodeOffset(boolean b) {
+ this.f = b ? 1 : 0;
+ }
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidClassVersion.java b/asm-test/src/resources/java/invalid/InvalidClassVersion.java
new file mode 100644
index 00000000..0976ce54
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidClassVersion.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidClassVersion {}
diff --git a/asm-test/src/resources/java/invalid/InvalidCodeLength.java b/asm-test/src/resources/java/invalid/InvalidCodeLength.java
new file mode 100644
index 00000000..4b298b14
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidCodeLength.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidCodeLength {
+
+ public final int f;
+
+ public InvalidCodeLength(boolean b) {
+ this.f = b ? 1 : 0;
+ }
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidConstantPoolIndex.java b/asm-test/src/resources/java/invalid/InvalidConstantPoolIndex.java
new file mode 100644
index 00000000..67e13410
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidConstantPoolIndex.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidConstantPoolIndex {}
diff --git a/asm-test/src/resources/java/invalid/InvalidConstantPoolReference.java b/asm-test/src/resources/java/invalid/InvalidConstantPoolReference.java
new file mode 100644
index 00000000..50c63bd3
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidConstantPoolReference.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidConstantPoolReference {}
diff --git a/asm-test/src/resources/java/invalid/InvalidCpInfoTag.java b/asm-test/src/resources/java/invalid/InvalidCpInfoTag.java
new file mode 100644
index 00000000..880ba883
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidCpInfoTag.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidCpInfoTag {}
diff --git a/asm-test/src/resources/java/invalid/InvalidElementValue.java b/asm-test/src/resources/java/invalid/InvalidElementValue.java
new file mode 100644
index 00000000..01c4212b
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidElementValue.java
@@ -0,0 +1,34 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.CLASS)
+public @interface InvalidElementValue {}
diff --git a/asm-test/src/resources/java/invalid/InvalidInsnTypeAnnotationTargetType.java b/asm-test/src/resources/java/invalid/InvalidInsnTypeAnnotationTargetType.java
new file mode 100644
index 00000000..4c38686e
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidInsnTypeAnnotationTargetType.java
@@ -0,0 +1,44 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE})
+@interface Nullable {}
+
+public class InvalidInsnTypeAnnotationTargetType {
+
+ public void method() {
+ @Nullable String local = null;
+ }
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidOpcode.java b/asm-test/src/resources/java/invalid/InvalidOpcode.java
new file mode 100644
index 00000000..efa1e6da
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidOpcode.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidOpcode {}
diff --git a/asm-test/src/resources/java/invalid/InvalidSourceDebugExtension.java b/asm-test/src/resources/java/invalid/InvalidSourceDebugExtension.java
new file mode 100644
index 00000000..77870093
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidSourceDebugExtension.java
@@ -0,0 +1,30 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidSourceDebugExtension {}
diff --git a/asm-test/src/resources/java/invalid/InvalidStackMapFrameType.java b/asm-test/src/resources/java/invalid/InvalidStackMapFrameType.java
new file mode 100644
index 00000000..d6592166
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidStackMapFrameType.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidStackMapFrameType {
+
+ public InvalidStackMapFrameType(String s) {}
+
+ public InvalidStackMapFrameType(boolean b) {
+ this(b ? "true" : "false");
+ }
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidTypeAnnotationTargetType.java b/asm-test/src/resources/java/invalid/InvalidTypeAnnotationTargetType.java
new file mode 100644
index 00000000..a0fbd5f6
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidTypeAnnotationTargetType.java
@@ -0,0 +1,42 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE})
+@interface Nullable {}
+
+public class InvalidTypeAnnotationTargetType {
+
+ public @Nullable String field;
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidVerificationTypeInfo.java b/asm-test/src/resources/java/invalid/InvalidVerificationTypeInfo.java
new file mode 100644
index 00000000..56a08944
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidVerificationTypeInfo.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidVerificationTypeInfo {
+
+ public InvalidVerificationTypeInfo(String s) {}
+
+ public InvalidVerificationTypeInfo(boolean b) {
+ this(b ? "true" : "false");
+ }
+}
diff --git a/asm-test/src/resources/java/invalid/InvalidWideOpcode.java b/asm-test/src/resources/java/invalid/InvalidWideOpcode.java
new file mode 100644
index 00000000..216bd16d
--- /dev/null
+++ b/asm-test/src/resources/java/invalid/InvalidWideOpcode.java
@@ -0,0 +1,36 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package invalid;
+
+public class InvalidWideOpcode {
+
+ public int m(int i) {
+ i += 1024;
+ return i;
+ }
+}
diff --git a/asm-test/src/resources/java/jdk11/AllInstructions.jasm b/asm-test/src/resources/java/jdk11/AllInstructions.jasm
new file mode 100644
index 00000000..007142f9
--- /dev/null
+++ b/asm-test/src/resources/java/jdk11/AllInstructions.jasm
@@ -0,0 +1,119 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk11;
+
+/**
+ * A class with all the JDK11 specific instructions. A corresponding class file can be generated
+ * with the OpenJDK asmtools (https://wiki.openjdk.java.net/display/CodeTools/asmtools),
+ * version 7 or more. Usage:
+ *
+ * java -jar asmtools.jar jasm AllInstructions.jasm
+ *
+ * @author Eric Bruneton
+ */
+super public class AllInstructions
+ version 55:0
+{
+
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+public Method m:"()Ljava/lang/Object;"
+ stack 1 locals 1
+{
+ ldc Dynamic REF_invokeStatic
+ :HandleOwner.handleField
+ :"(Ljava/lang/Object;)Ljava/lang/Object;"
+ :name
+ :"Ljava/lang/Object;" {
+ Dynamic REF_getStatic
+ :ArgumentHandleOwner.argumentHandleName
+ :"Ljava/lang/Object;"
+ :argumentName
+ :"Ljava/lang/Object;"
+ };
+ areturn;
+}
+
+public static Method primitiveExample:"()J"
+ stack 2 locals 0
+{
+ ldc2_w Dynamic REF_invokeStatic
+ :jdk11/AllInstructions.bsm
+ :"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J"
+ :test
+ :"J";
+ lreturn;
+}
+
+private static Method bsm:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J"
+ stack 2 locals 3
+{
+ bipush 42;
+ i2l;
+ lreturn;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+ stack 1 locals 2
+{
+ ldc Dynamic REF_invokeStatic
+ :java/lang/invoke/LambdaMetafactory.metafactory
+ :"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/Object;"
+ :run
+ :"Ljava/lang/Runnable;" {
+ MethodType "()V",
+ MethodHandle REF_invokeStatic:AllInstructions.lambda$main$0:"()V",
+ MethodType "()V"
+ };
+ astore_1;
+ aload_1;
+ invokeinterface InterfaceMethod java/lang/Runnable.run:"()V", 1;
+ return;
+}
+
+private static synthetic Method lambda$main$0:"()V"
+ stack 2 locals 0
+{
+ getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
+ ldc String "hello condy";
+ invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
+ return;
+}
+
+public static final InnerClass Lookup=
+ class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles;
+
+} // end Class AllInstructions
+
diff --git a/asm-test/src/resources/java/jdk11/AllStructures$Nested.jasm b/asm-test/src/resources/java/jdk11/AllStructures$Nested.jasm
new file mode 100644
index 00000000..f9e2e03a
--- /dev/null
+++ b/asm-test/src/resources/java/jdk11/AllStructures$Nested.jasm
@@ -0,0 +1,53 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk11;
+
+/**
+ * A class with all the JDK11 specific class file features. A corresponding class file can be
+ * generated with the OpenJDK asmtools (https://wiki.openjdk.java.net/display/CodeTools/asmtools),
+ * version 7 or more. Usage:
+ *
+ * java -jar asmtools.jar jasm AllStructures.jasm
+ *
+ * @author Eric Bruneton
+ */
+super public class AllStructures$Nested
+ version 55:0
+{
+
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+NestHost AllStructures;
+} // end Class AllStructures$Nested
diff --git a/asm-test/src/resources/java/jdk11/AllStructures.jasm b/asm-test/src/resources/java/jdk11/AllStructures.jasm
new file mode 100644
index 00000000..61fcb028
--- /dev/null
+++ b/asm-test/src/resources/java/jdk11/AllStructures.jasm
@@ -0,0 +1,53 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk11;
+
+/**
+ * A class with JDK11 specific class file feature. A corresponding class file can be generated
+ * with the OpenJDK asmtools (https://wiki.openjdk.java.net/display/CodeTools/asmtools),
+ * version 7 or more. Usage:
+ *
+ * java -jar asmtools.jar jasm AllStructures.jasm
+ *
+ * @author Eric Bruneton
+ */
+super public class AllStructures
+ version 55:0
+{
+
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+NestMembers AllStructures$Nested;
+} // end Class AllStructures
diff --git a/asm-test/src/resources/java/jdk14/AllStructures.java b/asm-test/src/resources/java/jdk14/AllStructures.java
new file mode 100644
index 00000000..68cec501
--- /dev/null
+++ b/asm-test/src/resources/java/jdk14/AllStructures.java
@@ -0,0 +1,47 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk14;
+
+import annotations.IRCA;
+import annotations.VRCA;
+import annotations.VTUA;
+import annotations.ITUA;
+import java.util.List;
+
+// compiled using jdk-14/bin/javac -source 14 --enable-preview jdk14/AllStructures.java
+public class AllStructures {
+ record RecordSubType(
+ @IRCA(v = 0) @VRCA(v = 1) @VTUA(v = 2) @ITUA(v = 3) int component1,
+ @IRCA(v = 4) @VRCA(v = 5) @VTUA(v = 6) @ITUA(v = 7) List<String> component2) {
+
+ }
+
+ record EmptyRecord() {
+
+ }
+} \ No newline at end of file
diff --git a/asm-test/src/resources/java/jdk15/AllStructures.java b/asm-test/src/resources/java/jdk15/AllStructures.java
new file mode 100644
index 00000000..c8aa0ac6
--- /dev/null
+++ b/asm-test/src/resources/java/jdk15/AllStructures.java
@@ -0,0 +1,37 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk15;
+
+public sealed interface AllStructures {
+ final class ClassSubType implements AllStructures {
+
+ }
+ record RecordSubType(int component1, String component2) implements AllStructures {
+
+ }
+}
diff --git a/asm-test/src/resources/java/jdk3/AllInstructions.java b/asm-test/src/resources/java/jdk3/AllInstructions.java
new file mode 100755
index 00000000..ba4a7669
--- /dev/null
+++ b/asm-test/src/resources/java/jdk3/AllInstructions.java
@@ -0,0 +1,285 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk3;
+
+/**
+ * Class which, compiled with the JDK 1.3.0, produces all the JVM instructions from that version, in
+ * particular jsr and ret (except nop and swap; wide instructions are included in LargeMethod). Must
+ * be compiled with "javac -g".
+ */
+class AllInstructions {
+ private int f;
+ private long g;
+ private AllInstructions field;
+ private static AllInstructions staticField;
+
+ AllInstructions() {}
+
+ AllInstructions(int v0, float v1, long v2, double v3, Object v4) {}
+
+ public static int intInstructions(
+ int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
+ boolean b0 = v0 < -1;
+ boolean b1 = v1 > 1;
+ boolean b2 = v2 <= 2;
+ boolean b3 = v3 >= 3;
+ boolean b4 = v4 == 4;
+ boolean b5 = v5 != 5;
+ v0 = b0 ? (v6 + 5) : (v6 - 5);
+ v1 = b1 ? (v7 * 100) : (v7 / 100);
+ v2 = b2 ? (v8 % 10000) : (~v8);
+ v3 = b3 ? (v0 & 1000000) : (v0 | 1000000);
+ v4 = b4 ? (v1 ^ v2) : (v1 << v2);
+ v5 = b5 ? (v2 >> v3) : (v2 >>> v3);
+ v6 += 1;
+ v7 = v6 < 0 ? -v6 : v6;
+ v1 = v0 < 0 ? v1 : v2;
+ v2 = v1 > 0 ? v2 : v3;
+ v3 = v2 <= 0 ? v3 : v4;
+ v4 = v3 >= 0 ? v4 : v5;
+ v5 = v4 == 0 ? v5 : v6;
+ v6 = v5 != 0 ? v6 : v7;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static long longInstructions(
+ long v0, long v1, long v2, long v3, long v4, long v5, long v6, long v7, long v8) {
+ boolean b0 = v0 < -1L;
+ boolean b1 = v1 > 1L;
+ boolean b2 = v2 <= 2L;
+ boolean b3 = v3 >= 3L;
+ boolean b4 = v4 == 4L;
+ boolean b5 = v5 != 5L;
+ v0 = b0 ? (v6 + 5L) : (v6 - 5L);
+ v1 = b1 ? (v7 * 100L) : (v7 / 100L);
+ v2 = b2 ? (v8 % 10000L) : (~v8);
+ v3 = b3 ? (v0 & 1000000L) : (v0 | 1000000L);
+ v4 = b4 ? (v1 ^ v2) : (v1 << v2);
+ v5 = b5 ? (v2 >> v3) : (v2 >>> v3);
+ v6 += 1L;
+ v7 = v6 < 0L ? -v6 : v6;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static float floatInstructions(
+ float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8) {
+ boolean b0 = v0 < -1f;
+ boolean b1 = v1 > 1f;
+ boolean b2 = v2 <= 2f;
+ boolean b3 = v3 >= 3f;
+ boolean b4 = v4 == 4f;
+ boolean b5 = v5 != 5f;
+ v0 = b0 ? (v6 + 5f) : (v6 - 5f);
+ v1 = b1 ? (v7 * 100f) : (v7 / 100f);
+ v2 = b2 ? (v8 % 10000f) : v8;
+ v3 = b3 ? -v3 : v3;
+ v4 = b4 ? -v4 : v4;
+ v5 = b5 ? -v5 : v5;
+ v6 += 1f;
+ v7 = v6 < 0f ? -v6 : v6;
+ v8 = v7;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static double doubleInstructions(
+ double v0,
+ double v1,
+ double v2,
+ double v3,
+ double v4,
+ double v5,
+ double v6,
+ double v7,
+ double v8) {
+ boolean b0 = v0 < -1d;
+ boolean b1 = v1 > 1d;
+ boolean b2 = v2 <= 2d;
+ boolean b3 = v3 >= 3d;
+ boolean b4 = v4 == 4d;
+ boolean b5 = v5 != 5d;
+ v0 = b0 ? (v6 + 5d) : (v6 - 5d);
+ v1 = b1 ? (v7 * 100d) : (v7 / 100d);
+ v2 = b2 ? (v8 % 10000d) : v8;
+ v3 = b3 ? -v3 : v3;
+ v4 = b4 ? -v4 : v4;
+ v5 = b5 ? -v5 : v5;
+ v6 += 1d;
+ v7 = v6 < 0d ? -v6 : v6;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static double castInstructions(int v0, long v1, long v2) {
+ byte v3 = (byte) v0;
+ char v4 = (char) v1;
+ short v5 = (short) v2;
+ long v6 = (long) v3;
+ float v7 = (float) v4;
+ double v8 = (double) v5;
+ v1 = v6;
+ v2 = v1;
+ v6 = (long) v8;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static float castInstructions(float v0, double v1, double v2) {
+ byte v3 = (byte) v0;
+ char v4 = (char) v1;
+ short v5 = (short) v2;
+ long v6 = (long) v3;
+ float v7 = (float) v4;
+ double v8 = (double) v5;
+ v1 = v6;
+ v2 = v1;
+ v6 = (long) v7;
+ return (float) (v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8);
+ }
+
+ public static Object objectInstructions(Object v0, Object v1, Object v2, Object v3, Object v4) {
+ boolean b0 = v0 == v1;
+ boolean b1 = v1 != v2;
+ boolean b2 = v2 == null;
+ boolean b3 = v3 != null;
+ boolean b4 = v4 instanceof String;
+ v0 = b0 ? null : v0;
+ v1 = b1 ? v1 : v0;
+ v2 = b2 ? v2 : v1;
+ v3 = b3 ? v3 : v2;
+ v4 = b4 ? new Integer(((String) v4).length()) : v3;
+ return v4;
+ }
+
+ public static Object[] arrayInstructions(
+ byte[] v0, char[] v1, short[] v2, int[] v3, long[] v4, float[] v5, double[] v6, Object[] v7) {
+ v0[1] = v0[0];
+ v1[1] = v1[0];
+ v2[1] = v2[0];
+ v3[1] = v3[0];
+ v4[1] = v4[0];
+ v5[1] = v5[0];
+ v6[1] = v6[0];
+ v7[1] = v7[0];
+ Object[] v8 = new Object[v7.length];
+ v8[0] = new int[4][8][16];
+ return v8;
+ }
+
+ public void fieldInstructions() {
+ AllInstructions c = field;
+ field = staticField;
+ staticField = c;
+ }
+
+ public void methodInstructions(Runnable v0) {
+ AllInstructions c = new AllInstructions();
+ c.fieldInstructions();
+ monitorInstructions(c);
+ v0.run();
+ }
+
+ public static int lookupSwitchInstruction(int v0) {
+ switch (v0) {
+ case 1000:
+ return 1;
+ case 10000:
+ return 2;
+ case 100000:
+ return 3;
+ default:
+ return -1;
+ }
+ }
+
+ public static int tableSwitchInstruction(int v0) {
+ switch (v0) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 3;
+ default:
+ return -1;
+ }
+ }
+
+ public static String monitorInstructions(Object v0) {
+ synchronized (v0) {
+ return v0.toString();
+ }
+ }
+
+ public int dupX1Instruction() {
+ return f++;
+ }
+
+ public void dup2Instruction(long[] v0, int i, int j) {
+ v0[i] |= (1L << j);
+ }
+
+ public long dup2X1Instruction() {
+ return g++;
+ }
+
+ public void dup2X1InstructionVariant(String[] v0, int i, Object o) {
+ v0[i] += " " + o.toString();
+ }
+
+ public void dupX2Instruction(int[] v0, int[] v1) {
+ v0[0] = v1[0] = 0;
+ }
+
+ public void dup2X2Instruction(long[] v0, long[] v1) {
+ v0[0] = v1[0] = 0;
+ }
+
+ public void popInstructions() {
+ dupX1Instruction();
+ dup2X1Instruction();
+ }
+
+ public int jsrAndRetInstructions(int v0) throws Exception {
+ int u0 = v0 + 1;
+ try {
+ u0 = jsrAndRetInstructions(u0);
+ } catch (Throwable t) {
+ return -1;
+ } finally {
+ u0++;
+ }
+ return u0;
+ }
+
+ public Object readNullArray() {
+ Object[] array = null;
+ try {
+ return array[0];
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+}
diff --git a/asm-test/src/resources/java/jdk3/AllStructures.java b/asm-test/src/resources/java/jdk3/AllStructures.java
new file mode 100755
index 00000000..7eaa3b9a
--- /dev/null
+++ b/asm-test/src/resources/java/jdk3/AllStructures.java
@@ -0,0 +1,117 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk3;
+
+import java.io.Serializable;
+
+/**
+ * Class which, compiled with the JDK 1.3.0, produces all the class file structures from that
+ * version. Must be compiled with "javac -g".
+ */
+abstract class AllStructures implements Runnable, Cloneable, Serializable {
+
+ private static final String UTF8 = "\u0008\u0080\u0800\u8000";
+ private static final long serialVersionUID = 123456L;
+
+ public int f0;
+ protected float f1;
+ long f2;
+ private double f3;
+ static AllStructures f4;
+ final byte f5 = 1;
+ transient char f6;
+ volatile short f7;
+ boolean f8;
+
+ static {
+ f4 = null;
+ }
+
+ public int m0() {
+ return f0;
+ }
+
+ protected float m1() {
+ return f1;
+ }
+
+ long m2() {
+ return f2;
+ }
+
+ private double m3() {
+ return f3;
+ }
+
+ static AllStructures m4() {
+ return f4;
+ }
+
+ final byte m5() {
+ return f5;
+ }
+
+ strictfp char m6() {
+ return f6;
+ }
+
+ short m7() {
+ return f7;
+ }
+
+ abstract boolean m8();
+
+ public static void main(String[] args) {}
+
+ public void run() {}
+
+ public synchronized Object clone() {
+ return this;
+ }
+
+ private native void nativeMethod();
+
+ private Runnable anonymousInnerClass() throws Exception {
+ if (f0 > 0) {
+ throw new Exception();
+ }
+ return new Runnable() {
+ public void run() {
+ new InnerClass(new InnerClass(f3 + m3()).f0);
+ }
+ };
+ }
+
+ private class InnerClass {
+ private final double f0;
+
+ private InnerClass(double f0) {
+ this.f0 = f0;
+ }
+ }
+}
diff --git a/asm-test/src/resources/java/jdk3/DumpArtificialStructures.java b/asm-test/src/resources/java/jdk3/DumpArtificialStructures.java
new file mode 100644
index 00000000..3701472d
--- /dev/null
+++ b/asm-test/src/resources/java/jdk3/DumpArtificialStructures.java
@@ -0,0 +1,180 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk3;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.CodeComment;
+import org.objectweb.asm.Comment;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Generates a class with structures, instructions and patterns that cannot be produced by compiling
+ * a Java source file with the javac compiler. This includes:
+ *
+ * <ul>
+ * <li>the class, field and method Synthetic attribute (now replaced with an access flag),
+ * <li>the StackMap attribute (which was used for pre-verification in J2ME CLDC 1.1),
+ * <li>non standard class, field, method and code attributes,
+ * <li>the nop and swap instructions,
+ * <li>some variants of the dup_x2 and dup2_x2 instructions,
+ * <li>several line numbers per bytecode offset.
+ * </ul>
+ *
+ * Ideally we should not use ASM to generate this class (which is later used to test ASM), but this
+ * would be hard to do.
+ *
+ * @author Eric Bruneton
+ */
+public class DumpArtificialStructures implements Opcodes {
+
+ public static void main(String[] args) throws IOException {
+ FileOutputStream fileOutputStream = new FileOutputStream("ArtificialStructures.class");
+ fileOutputStream.write(dump());
+ fileOutputStream.close();
+ }
+
+ private static byte[] dump() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ FieldVisitor fieldVisitor;
+ MethodVisitor methodVisitor;
+
+ classWriter.visit(
+ V1_3, ACC_PUBLIC + ACC_SUPER, "jdk3/ArtificialStructures", null, "java/lang/Object", null);
+
+ classWriter.visitSource("ArtificialStructures.java", "source-debug");
+
+ classWriter.visitAttribute(new Comment());
+
+ fieldVisitor = classWriter.visitField(ACC_PUBLIC + ACC_SYNTHETIC, "f", "I", null, null);
+ fieldVisitor.visitAttribute(new Comment());
+ fieldVisitor.visitEnd();
+
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC + ACC_SYNTHETIC, "<init>", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitAttribute(new Comment());
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(NOP);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitAttribute(new CodeComment());
+ methodVisitor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(0, "<init>", "(Z)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(SWAP);
+ Label elseLabel = new Label();
+ methodVisitor.visitJumpInsn(IFEQ, elseLabel);
+ methodVisitor.visitLdcInsn("1");
+ Label endIfLabel = new Label();
+ methodVisitor.visitJumpInsn(GOTO, endIfLabel);
+ methodVisitor.visitLabel(elseLabel);
+ methodVisitor.visitLineNumber(1, elseLabel);
+ methodVisitor.visitLineNumber(3, elseLabel);
+ methodVisitor.visitLdcInsn("0");
+ methodVisitor.visitLabel(endIfLabel);
+ methodVisitor.visitLineNumber(5, endIfLabel);
+ methodVisitor.visitLineNumber(7, endIfLabel);
+ methodVisitor.visitLineNumber(11, endIfLabel);
+ methodVisitor.visitLineNumber(13, endIfLabel);
+ methodVisitor.visitLineNumber(17, endIfLabel);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "jdk3/ArtificialStructures", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup_x2", "(IJ)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(LLOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitInsn(DUP_X2);
+ methodVisitor.visitInsn(I2L);
+ methodVisitor.visitInsn(LADD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "jdk3/ArtificialStructures", "dup_x2", "(IJ)V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(IIII)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ILOAD, 3);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitInsn(DUP2_X2);
+ methodVisitor.visitInsn(IADD);
+ methodVisitor.visitInsn(IADD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(IIII)V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(IIJ)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(LLOAD, 2);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitInsn(DUP2_X2);
+ methodVisitor.visitInsn(IADD);
+ methodVisitor.visitInsn(I2L);
+ methodVisitor.visitInsn(LADD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(IIJ)V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(JD)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(DLOAD, 2);
+ methodVisitor.visitVarInsn(LLOAD, 0);
+ methodVisitor.visitInsn(DUP2_X2);
+ methodVisitor.visitInsn(L2D);
+ methodVisitor.visitInsn(DADD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(JD)V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ classWriter.visitEnd();
+ return classWriter.toByteArray();
+ }
+}
diff --git a/asm-test/src/resources/java/jdk3/LargeMethod.java b/asm-test/src/resources/java/jdk3/LargeMethod.java
new file mode 100755
index 00000000..0cadabf7
--- /dev/null
+++ b/asm-test/src/resources/java/jdk3/LargeMethod.java
@@ -0,0 +1,536 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk3;
+
+/**
+ * Class which, compiled with the JDK 1.3.0, produces all the "wide" JVM instructions (e.g. goto_w,
+ * jsr_w, etc). Must be compiled with "javac -g".
+ */
+public class LargeMethod {
+ private int f;
+
+ LargeMethod(int v0, float v1, long v2, double v3, Object v4) {}
+
+ public LargeMethod wideInstructions(
+ int v0,
+ long v1,
+ long v2,
+ long v3,
+ long v4,
+ long v5,
+ long v6,
+ long v7,
+ long v8,
+ long v9,
+ long v10,
+ long v11,
+ long v12,
+ long v13,
+ long v14,
+ long v15,
+ long v16,
+ long v17,
+ long v18,
+ long v19,
+ long v20,
+ long v21,
+ long v22,
+ long v23,
+ long v24,
+ long v25,
+ long v26,
+ long v27,
+ long v28,
+ long v29,
+ long v30,
+ long v31,
+ long v32,
+ long v33,
+ long v34,
+ long v35,
+ long v36,
+ long v37,
+ long v38,
+ long v39,
+ long v40,
+ long v41,
+ long v42,
+ long v43,
+ long v44,
+ long v45,
+ long v46,
+ long v47,
+ long v48,
+ long v49,
+ long v50,
+ long v51,
+ long v52,
+ long v53,
+ long v54,
+ long v55,
+ long v56,
+ long v57,
+ long v58,
+ long v59,
+ long v60,
+ long v61,
+ long v62,
+ long v63,
+ long v64,
+ long v65,
+ long v66,
+ long v67,
+ long v68,
+ long v69,
+ long v70,
+ long v71,
+ long v72,
+ long v73,
+ long v74,
+ long v75,
+ long v76,
+ long v77,
+ long v78,
+ long v79,
+ long v80,
+ long v81,
+ long v82,
+ long v83,
+ long v84,
+ long v85,
+ long v86,
+ long v87,
+ long v88,
+ long v89,
+ long v90,
+ long v91,
+ long v92,
+ long v93,
+ long v94,
+ long v95,
+ long v96,
+ long v97,
+ long v98,
+ long v99,
+ long v100,
+ long v101,
+ long v102,
+ long v103,
+ long v104,
+ long v105,
+ long v106,
+ long v107,
+ long v108,
+ long v109,
+ long v110,
+ long v111,
+ long v112,
+ long v113,
+ long v114,
+ long v115,
+ long v116,
+ long v117,
+ long v118,
+ long v119,
+ long v120,
+ long v121,
+ long v122,
+ long v123,
+ int v124,
+ float v125,
+ long v126,
+ double v127,
+ Object v128) {
+ int[] u0 = {
+ 70001, 70002, 70003, 70004, 70005, 70006, 70007, 70008, 70009, 70010, 70011, 70012, 70013,
+ 70014, 70015, 70016, 70017, 70018, 70019, 70020, 70021, 70022, 70023, 70024, 70025, 70026,
+ 70027, 70028, 70029, 70030, 70031, 70032, 70033, 70034, 70035, 70036, 70037, 70038, 70039,
+ 70040, 70041, 70042, 70043, 70044, 70045, 70046, 70047, 70048, 70049, 70050, 70051, 70052,
+ 70053, 70054, 70055, 70056, 70057, 70058, 70059, 70060, 70061, 70062, 70063, 70064, 70065,
+ 70066, 70067, 70068, 70069, 70070, 70071, 70072, 70073, 70074, 70075, 70076, 70077, 70078,
+ 70079, 70080, 70081, 70082, 70083, 70084, 70085, 70086, 70087, 70088, 70089, 70090, 70091,
+ 70092, 70093, 70094, 70095, 70096, 70097, 70098, 70099, 70100, 70101, 70102, 70103, 70104,
+ 70105, 70106, 70107, 70108, 70109, 70110, 70111, 70112, 70113, 70114, 70115, 70116, 70117,
+ 70118, 70119, 70120, 70121, 70122, 70123, 70124, 70125, 70126, 70127, 70128, 70129, 70130,
+ 70131, 70132, 70133, 70134, 70135, 70136, 70137, 70138, 70139, 70140, 70141, 70142, 70143,
+ 70144, 70145, 70146, 70147, 70148, 70149, 70150, 70151, 70152, 70153, 70154, 70155, 70156,
+ 70157, 70158, 70159, 70160, 70161, 70162, 70163, 70164, 70165, 70166, 70167, 70168, 70169,
+ 70170, 70171, 70172, 70173, 70174, 70175, 70176, 70177, 70178, 70179, 70180, 70181, 70182,
+ 70183, 70184, 70185, 70186, 70187, 70188, 70189, 70190, 70191, 70192, 70193, 70194, 70195,
+ 70196, 70197, 70198, 70199, 70200, 70201, 70202, 70203, 70204, 70205, 70206, 70207, 70208,
+ 70209, 70210, 70211, 70212, 70213, 70214, 70215, 70216, 70217, 70218, 70219, 70220, 70221,
+ 70222, 70223, 70224, 70225, 70226, 70227, 70228, 70229, 70230, 70231, 70232, 70233, 70234,
+ 70235, 70236, 70237, 70238, 70239, 70240, 70241, 70242, 70243, 70244, 70245, 70246, 70247,
+ 70248, 70249, 70250, 70251, 70252, 70253, 70254, 70255
+ };
+ int u124 = v124 < 0 ? -v124 : v124;
+ float u125 = v125 < 0f ? -v125 : v125;
+ long u126 = v126 < 0L ? -v126 : v126;
+ double u127 = v127 < 0d ? -v127 : v127;
+ String u128 = v128 == null ? null : v128.toString();
+ try {
+ for (int i = 0; i < v0; ++i) {
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ }
+ } catch (Throwable t) {
+ return null;
+ } finally {
+ u0 = null;
+ }
+ return new LargeMethod(u124 + u0[f % u0.length], u125, u126, u127, u128);
+ }
+}
diff --git a/asm-test/src/resources/java/jdk3/SubOptimalMaxStackAndLocals.jasm b/asm-test/src/resources/java/jdk3/SubOptimalMaxStackAndLocals.jasm
new file mode 100644
index 00000000..7e21bb5f
--- /dev/null
+++ b/asm-test/src/resources/java/jdk3/SubOptimalMaxStackAndLocals.jasm
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk3;
+
+/**
+ * A class with valid but non optimal max_stack and max_locals, on purpose (to test cases like
+ * this). A corresponding class file can be generated with the OpenJDK asmtools
+ * (https://wiki.openjdk.java.net/display/CodeTools/asmtools), version 7 or more. Usage:
+ *
+ * java -jar asmtools.jar jasm SubOptimalMaxStackAndLocals.jasm
+ *
+ * @author Eric Bruneton
+ */
+super public class SubOptimalMaxStackAndLocals
+ version 47:0
+{
+
+public Method "<init>":"()V"
+ stack 2 locals 3
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+} // end Class SubOptimalMaxStackAndLocals
diff --git a/asm-test/src/resources/java/jdk5/AllInstructions.java b/asm-test/src/resources/java/jdk5/AllInstructions.java
new file mode 100755
index 00000000..3137ee16
--- /dev/null
+++ b/asm-test/src/resources/java/jdk5/AllInstructions.java
@@ -0,0 +1,288 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk5;
+
+/**
+ * Class which, compiled with the JDK 1.5.0, produces the new JVM instructions from that version
+ * (compared to JDK 1.3.0). Also contain all the other instructions that can be used in JDK 1.5
+ * classes (which excludes jsr and ret), so that ASM classes which don't support jsr or ret (and
+ * therefore can't be tested with jdk3.AllInstructions) can still be tested on all instructions.
+ * Must be compiled with "javac -g".
+ */
+class AllInstructions {
+ private Class c;
+ private Class d;
+ private int f;
+ private long g;
+ private AllInstructions field;
+ private static AllInstructions staticField;
+
+ AllInstructions() {}
+
+ AllInstructions(int v0, float v1, long v2, double v3, Object v4) {}
+
+ // New instruction in JDK 1.5.
+ public void ldcWithClassConstant() {
+ c = AllInstructions.class;
+ d = AllInstructions[].class;
+ }
+
+ public static int intInstructions(
+ int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
+ boolean b0 = v0 < -1;
+ boolean b1 = v1 > 1;
+ boolean b2 = v2 <= 2;
+ boolean b3 = v3 >= 3;
+ boolean b4 = v4 == 4;
+ boolean b5 = v5 != 5;
+ v0 = b0 ? (v6 + 5) : (v6 - 5);
+ v1 = b1 ? (v7 * 100) : (v7 / 100);
+ v2 = b2 ? (v8 % 10000) : (~v8);
+ v3 = b3 ? (v0 & 1000000) : (v0 | 1000000);
+ v4 = b4 ? (v1 ^ v2) : (v1 << v2);
+ v5 = b5 ? (v2 >> v3) : (v2 >>> v3);
+ v6 += 1;
+ v7 = v6 < 0 ? -v6 : v6;
+ v1 = v0 < 0 ? v1 : v2;
+ v2 = v1 > 0 ? v2 : v3;
+ v3 = v2 <= 0 ? v3 : v4;
+ v4 = v3 >= 0 ? v4 : v5;
+ v5 = v4 == 0 ? v5 : v6;
+ v6 = v5 != 0 ? v6 : v7;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static long longInstructions(
+ long v0, long v1, long v2, long v3, long v4, long v5, long v6, long v7, long v8) {
+ boolean b0 = v0 < -1L;
+ boolean b1 = v1 > 1L;
+ boolean b2 = v2 <= 2L;
+ boolean b3 = v3 >= 3L;
+ boolean b4 = v4 == 4L;
+ boolean b5 = v5 != 5L;
+ v0 = b0 ? (v6 + 5L) : (v6 - 5L);
+ v1 = b1 ? (v7 * 100L) : (v7 / 100L);
+ v2 = b2 ? (v8 % 10000L) : (~v8);
+ v3 = b3 ? (v0 & 1000000L) : (v0 | 1000000L);
+ v4 = b4 ? (v1 ^ v2) : (v1 << v2);
+ v5 = b5 ? (v2 >> v3) : (v2 >>> v3);
+ v6 += 1L;
+ v7 = v6 < 0L ? -v6 : v6;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static float floatInstructions(
+ float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8) {
+ boolean b0 = v0 < -1f;
+ boolean b1 = v1 > 1f;
+ boolean b2 = v2 <= 2f;
+ boolean b3 = v3 >= 3f;
+ boolean b4 = v4 == 4f;
+ boolean b5 = v5 != 5f;
+ v0 = b0 ? (v6 + 5f) : (v6 - 5f);
+ v1 = b1 ? (v7 * 100f) : (v7 / 100f);
+ v2 = b2 ? (v8 % 10000f) : v8;
+ v3 = b3 ? -v3 : v3;
+ v4 = b4 ? -v4 : v4;
+ v5 = b5 ? -v5 : v5;
+ v6 += 1f;
+ v7 = v6 < 0f ? -v6 : v6;
+ v8 = v7;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static double doubleInstructions(
+ double v0,
+ double v1,
+ double v2,
+ double v3,
+ double v4,
+ double v5,
+ double v6,
+ double v7,
+ double v8) {
+ boolean b0 = v0 < -1d;
+ boolean b1 = v1 > 1d;
+ boolean b2 = v2 <= 2d;
+ boolean b3 = v3 >= 3d;
+ boolean b4 = v4 == 4d;
+ boolean b5 = v5 != 5d;
+ v0 = b0 ? (v6 + 5d) : (v6 - 5d);
+ v1 = b1 ? (v7 * 100d) : (v7 / 100d);
+ v2 = b2 ? (v8 % 10000d) : v8;
+ v3 = b3 ? -v3 : v3;
+ v4 = b4 ? -v4 : v4;
+ v5 = b5 ? -v5 : v5;
+ v6 += 1d;
+ v7 = v6 < 0d ? -v6 : v6;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static double castInstructions(int v0, long v1, long v2) {
+ byte v3 = (byte) v0;
+ char v4 = (char) v1;
+ short v5 = (short) v2;
+ long v6 = (long) v3;
+ float v7 = (float) v4;
+ double v8 = (double) v5;
+ v1 = v6;
+ v2 = v1;
+ v6 = (long) v8;
+ return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+ }
+
+ public static float castInstructions(float v0, double v1, double v2) {
+ byte v3 = (byte) v0;
+ char v4 = (char) v1;
+ short v5 = (short) v2;
+ long v6 = (long) v3;
+ float v7 = (float) v4;
+ double v8 = (double) v5;
+ v1 = v6;
+ v2 = v1;
+ v6 = (long) v7;
+ return (float) (v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8);
+ }
+
+ public static Object objectInstructions(Object v0, Object v1, Object v2, Object v3, Object v4) {
+ boolean b0 = v0 == v1;
+ boolean b1 = v1 != v2;
+ boolean b2 = v2 == null;
+ boolean b3 = v3 != null;
+ boolean b4 = v4 instanceof String;
+ v0 = b0 ? null : v0;
+ v1 = b1 ? v1 : v0;
+ v2 = b2 ? v2 : v1;
+ v3 = b3 ? v3 : v2;
+ v4 = b4 ? new Integer(((String) v4).length()) : v3;
+ return v4;
+ }
+
+ public static Object[] arrayInstructions(
+ byte[] v0, char[] v1, short[] v2, int[] v3, long[] v4, float[] v5, double[] v6, Object[] v7) {
+ v0[1] = v0[0];
+ v1[1] = v1[0];
+ v2[1] = v2[0];
+ v3[1] = v3[0];
+ v4[1] = v4[0];
+ v5[1] = v5[0];
+ v6[1] = v6[0];
+ v7[1] = v7[0];
+ Object[] v8 = new Object[v7.length];
+ v8[0] = new int[4][8][16];
+ return v8;
+ }
+
+ public void fieldInstructions() {
+ AllInstructions c = field;
+ field = staticField;
+ staticField = c;
+ }
+
+ public void methodInstructions(Runnable v0) {
+ AllInstructions c = new AllInstructions();
+ c.fieldInstructions();
+ monitorInstructions(c);
+ v0.run();
+ }
+
+ public static int lookupSwitchInstruction(int v0) {
+ switch (v0) {
+ case 1000:
+ return 1;
+ case 10000:
+ return 2;
+ case 100000:
+ return 3;
+ default:
+ return -1;
+ }
+ }
+
+ public static int tableSwitchInstruction(int v0) {
+ switch (v0) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 3;
+ default:
+ return -1;
+ }
+ }
+
+ public static String monitorInstructions(Object v0) {
+ synchronized (v0) {
+ return v0.toString();
+ }
+ }
+
+ public int dupX1Instruction() {
+ return f++;
+ }
+
+ public long dup2X1Instruction() {
+ return g++;
+ }
+
+ public void dupX2Instruction(int[] v0, int[] v1) {
+ v0[0] = v1[0] = 0;
+ }
+
+ public void dup2X2Instruction(long[] v0, long[] v1) {
+ v0[0] = v1[0] = 0;
+ }
+
+ public void popInstructions() {
+ dupX1Instruction();
+ dup2X1Instruction();
+ }
+
+ // With JDK1.5, this code no longer produces jsr or ret instructions.
+ public int jsrAndRetInstructions(int v0) throws Exception {
+ int u0 = v0 + 1;
+ try {
+ u0 = jsrAndRetInstructions(u0);
+ } catch (Throwable t) {
+ return -1;
+ } finally {
+ u0++;
+ }
+ return u0;
+ }
+
+ public Object readNullArray() {
+ Object[] array = null;
+ try {
+ return array[0];
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+}
diff --git a/asm-test/src/resources/java/jdk5/AllStructures.java b/asm-test/src/resources/java/jdk5/AllStructures.java
new file mode 100755
index 00000000..89fa92fa
--- /dev/null
+++ b/asm-test/src/resources/java/jdk5/AllStructures.java
@@ -0,0 +1,225 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk5;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Class which, compiled with the JDK 1.5.0, produces the new class file structures from that
+ * version (compared to JDK 1.3.0). Must be compiled with "javac -g".
+ */
+@Deprecated
+@AllStructures.InvisibleAnnotation(
+ byteValue = 0,
+ charValue = 0,
+ booleanValue = false,
+ intValue = 0,
+ shortValue = 0,
+ longValue = 0L,
+ floatValue = 0f,
+ doubleValue = 0d,
+ stringValue = "0",
+ classValue = AllStructures.class,
+ enumValue = AllStructures.EnumClass.VALUE0,
+ annotationValue = @Deprecated,
+ byteArrayValue = {0},
+ charArrayValue = {'0'},
+ booleanArrayValue = {false},
+ intArrayValue = {0},
+ shortArrayValue = {0},
+ longArrayValue = {0L},
+ floatArrayValue = {0f},
+ doubleArrayValue = {0d},
+ stringArrayValue = {"0"},
+ classArrayValue = {AllStructures.class, int.class, int[].class},
+ enumArrayValue = {AllStructures.EnumClass.VALUE0},
+ annotationArrayValue = {@Deprecated},
+ otherArrayValue = {}
+)
+class AllStructures<
+ U0,
+ U1 extends Number,
+ U2 extends List<String>,
+ U3 extends List<?>,
+ U4 extends List<? extends Number>,
+ U5 extends List<? super Number>,
+ U6 extends Number & Runnable & Cloneable>
+ implements Comparator<Integer> {
+
+ @Deprecated
+ @InvisibleAnnotation(otherArrayValue = {2})
+ public int f;
+
+ private U0 f0;
+ private U1 f1;
+ private U2 f2;
+ private U3 f3;
+ private U4 f4;
+ private U5 f5;
+ private U6 f6;
+
+ @Deprecated
+ @InvisibleAnnotation(otherArrayValue = {3})
+ public int m() {
+ return f;
+ }
+
+ public int n(
+ int p0,
+ @Deprecated @InvisibleAnnotation(otherArrayValue = {4}) float p1,
+ @Deprecated float p2,
+ long p3,
+ @InvisibleAnnotation(otherArrayValue = {5}) double p4) {
+ return f;
+ }
+
+ public U0 o() {
+ return f0;
+ }
+
+ <
+ U0,
+ U1 extends Number,
+ U2 extends List<String>,
+ U3 extends List<?>,
+ U4 extends List<? extends Number>,
+ U5 extends List<? super Number>,
+ U6 extends Number & Runnable & Cloneable,
+ U7 extends Exception,
+ U8 extends IOException>
+ void genericMethod(
+ List<U0> p0,
+ List<U1[]> p1,
+ List<U2[][]> p2,
+ List<U3> p3,
+ List<U4> p4,
+ List<U5> p5,
+ List<U6> p6,
+ AllStructures<U0, U1, U2, U3, U4, U5, U6>.InnerClass p7,
+ AllStructures<U0, U1, U2, U3, U4, U5, U6>.GenericInnerClass<U1> p8)
+ throws U7, U8 {}
+
+ int varArgsAutoBoxingAndForLoop(int... args) {
+ int total = 0;
+ for (int arg : args) {
+ total += arg;
+ }
+ return total;
+ }
+
+ void localClassConstructor(final String name) {
+ class LocalClass {
+ LocalClass(@Deprecated int value) {
+ System.out.println(name + value);
+ }
+ }
+ new LocalClass(42);
+ }
+
+ // Generates a bridge method.
+ public int compare(Integer a, Integer b) {
+ return a < b ? -1 : 1;
+ }
+
+ @Retention(RetentionPolicy.CLASS)
+ @interface InvisibleAnnotation {
+ byte byteValue() default 1;
+
+ char charValue() default '1';
+
+ boolean booleanValue() default true;
+
+ int intValue() default 1;
+
+ short shortValue() default 1;
+
+ long longValue() default 1L;
+
+ float floatValue() default 1f;
+
+ double doubleValue() default 1d;
+
+ String stringValue() default "1";
+
+ Class classValue() default Object.class;
+
+ EnumClass enumValue() default EnumClass.VALUE1;
+
+ Deprecated annotationValue() default @Deprecated;
+
+ byte[] byteArrayValue() default {1};
+
+ char[] charArrayValue() default {'1'};
+
+ boolean[] booleanArrayValue() default {true};
+
+ int[] intArrayValue() default {1};
+
+ short[] shortArrayValue() default {1};
+
+ long[] longArrayValue() default {1L};
+
+ float[] floatArrayValue() default {1f};
+
+ double[] doubleArrayValue() default {1d};
+
+ String[] stringArrayValue() default {"1"};
+
+ Class[] classArrayValue() default {Object.class, int.class, int[].class};
+
+ EnumClass[] enumArrayValue() default {EnumClass.VALUE1};
+
+ Deprecated[] annotationArrayValue() default {@Deprecated};
+
+ int[] otherArrayValue();
+ }
+
+ enum EnumClass {
+ VALUE0(0),
+ VALUE1(1),
+ VALUE2(2);
+
+ private int value;
+
+ private EnumClass(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ class InnerClass {}
+
+ class GenericInnerClass<T> {}
+}
diff --git a/asm-test/src/resources/java/jdk8/AllFrames.java b/asm-test/src/resources/java/jdk8/AllFrames.java
new file mode 100755
index 00000000..44be5d1b
--- /dev/null
+++ b/asm-test/src/resources/java/jdk8/AllFrames.java
@@ -0,0 +1,221 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk8;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Class which, compiled with the JDK 1.8.0, produces all the stack map frame types. Must be
+ * compiled with "javac -g -parameters".
+ */
+public class AllFrames {
+
+ Object o;
+ String s;
+ int f;
+
+ public AllFrames(Object o, String s) {
+ this.o = o;
+ this.s = s;
+ }
+
+ // Frame types: full_frame.
+ // Element types: null, uninitialized_this.
+ public AllFrames(boolean b) {
+ this(null, b ? "true" : "false");
+ }
+
+ // Frame types: full_frame.
+ // Element types: null, uninitialized.
+ public static AllFrames create(String s) {
+ return new AllFrames(null, s == null ? "" : s);
+ }
+
+ // Frame types: same, same_locals_1_stack_item, full_frame.
+ // Element types: primitive types and object.
+ public int m0(
+ boolean b,
+ byte y,
+ char c,
+ short s,
+ int i,
+ float f,
+ long l,
+ double d,
+ Object o,
+ Object[] p,
+ Object[][] q) {
+ return b
+ ? m0(!b, y, c, s, i - 1, f - 1f, l - 1l, d - 1d, o, p, q)
+ : m0(!b, y, c, s, i + 1, f + 1f, l + 1l, d + 1d, o, p, q);
+ }
+
+ // Element types: uninitialized (multiple per frame).
+ public String m0(byte[] bytes, boolean b) {
+ try {
+ return bytes == null ? null : new String(bytes, b ? "a" : "b");
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+
+ // Frame types: append.
+ // Element types: top.
+ public void m1(int i, int j) {
+ int k;
+ int l = j;
+ if (i < 0) {
+ i = -i;
+ }
+ }
+
+ // Frame types: chop.
+ public long m2(int n, boolean b) {
+ long total = 0;
+ if (b) {
+ int i = 0;
+ do {
+ total += i++;
+ } while (i < n);
+ } else {
+ long i = 0;
+ do {
+ total += i++;
+ } while (i < n);
+ }
+ return total;
+ }
+
+ // Frame types: same_frame_extended.
+ public int m3(int i) {
+ if (i < 0) {
+ i = i + i + i + i + i + i + i + i + i + i + i + i + i + i + i + i;
+ i = i + i + i + i + i + i + i + i + i + i + i + i + i + i + i + i;
+ }
+ return i;
+ }
+
+ // Frame types: same_locals_1_stack_item_frame_extended.
+ public void m4(int i) {
+ i = i + i + i + i + i + i + i + i + i + i + i + i + i + i + i + i;
+ i = i + i + i + i + i + i + i + i + i + i + i + i + i + i + i + i;
+ s = i == 0 ? "true" : "false";
+ }
+
+ // Frame merges: two non-array objects.
+ public static Number m5(boolean b) {
+ return b ? new Integer(1) : new Float(1);
+ }
+
+ // Frame merges: two single-dimensional arrays with object type elements.
+ public static Number[] m6(boolean b) {
+ return b ? new Integer[1] : new Float[1];
+ }
+
+ // Frame merges: two bi-dimensional arrays with object type elements.
+ public static Number[][] m7(boolean b) {
+ return b ? new Integer[1][1] : new Float[1][1];
+ }
+
+ // Frame merges: two bi-dimensional arrays with primitive type elements.
+ public static Object[] m8(boolean b) {
+ return b ? (Object[]) new byte[1][1] : (Object[]) new short[1][1];
+ }
+
+ // Frame merges: two single-dimensional arrays with mixed primitive / object type elements.
+ public static Object m9(boolean b) {
+ return b ? new byte[1] : new Float[1];
+ }
+
+ // Frame merges: two bi-dimensional arrays with mixed primitive / object type elements.
+ public static Object[] m10(boolean b) {
+ return b ? (Object[]) new byte[1][1] : (Object[]) new Float[1][];
+ }
+
+ // Frame merges: one and two dimensions arrays with identical element type.
+ public static Object m11(boolean b) {
+ return b ? new byte[1] : new byte[1][1];
+ }
+
+ // Frame merges: one and two dimensions arrays with mixed primitive / object type elements.
+ public static Object[] m12(boolean b) {
+ return b ? new Object[1] : new byte[1][1];
+ }
+
+ // Frame merges: two and three dimensions arrays with primitive type elements.
+ public static Object[] m13(boolean b) {
+ return b ? (Object[]) new byte[1][1] : (Object[]) new byte[1][1][1];
+ }
+
+ // Frame merges: three and four dimensions arrays with primitive type elements.
+ public static Object[][] m14(boolean b) {
+ return b ? (Object[][]) new byte[1][1][1] : (Object[][]) new byte[1][1][1][1];
+ }
+
+ // Frame merges: object type and single-dimensional array with primitive type elements.
+ public static Object m15(boolean b) {
+ return b ? new Integer(1) : new char[1];
+ }
+
+ // Frame merges: object type and single-dimensional array with object type elements.
+ public static Object m16(boolean b) {
+ return b ? new Integer(1) : new Float[1];
+ }
+
+ // Frame merges: two single-dimensional arrays with different primitive type elements.
+ public Object m17(boolean b) {
+ return b ? new int[0] : new boolean[0];
+ }
+
+ // Frame merges: two single-dimensional arrays with different primitive type elements.
+ public Object m18(boolean b) {
+ return b ? new short[0] : new float[0];
+ }
+
+ // Frame merges: two single-dimensional arrays with different primitive type elements.
+ public Object m19(boolean b) {
+ return b ? new double[0] : new long[0];
+ }
+
+ // Frame merges: null type and object type.
+ public static Object m20(boolean b) {
+ return b ? null : new Integer(1);
+ }
+
+ // Frame merges: object type and null type.
+ public static Object m21(boolean b) {
+ return b ? new Integer(1) : null;
+ }
+
+ // Frame AALOAD from null array (no frame in original class because ASM can't compute the exact
+ // same frame as javac, but usefull for tests that compute frame types at each instruction).
+ public static int m23() {
+ Integer[] array = null;
+ return array[0].intValue();
+ }
+}
diff --git a/asm-test/src/resources/java/jdk8/AllInstructions.java b/asm-test/src/resources/java/jdk8/AllInstructions.java
new file mode 100755
index 00000000..e151d761
--- /dev/null
+++ b/asm-test/src/resources/java/jdk8/AllInstructions.java
@@ -0,0 +1,45 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk8;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Class which, compiled with the JDK 1.8.0, produces the new JVM instructions from that version
+ * (compared to JDK 1.5.0). Must be compiled with "javac -g -parameters".
+ */
+class AllInstructions {
+ public void invokedynamic(List<String> strings) {
+ List<String> validStrings = Arrays.asList(new String[] {"a", "b", "c"});
+ strings.forEach(
+ (s) -> {
+ if (!validStrings.contains(s)) System.out.printf("Invalid string %s\n", s);
+ });
+ }
+}
diff --git a/asm-test/src/resources/java/jdk8/AllStructures.java b/asm-test/src/resources/java/jdk8/AllStructures.java
new file mode 100755
index 00000000..40b5b864
--- /dev/null
+++ b/asm-test/src/resources/java/jdk8/AllStructures.java
@@ -0,0 +1,152 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk8;
+
+import annotations.ICA;
+import annotations.IFA;
+import annotations.IMA;
+import annotations.IPA;
+import annotations.ITA;
+import annotations.ITPA;
+import annotations.ITUA;
+import annotations.IVA;
+import annotations.VCA;
+import annotations.VFA;
+import annotations.VMA;
+import annotations.VPA;
+import annotations.VTA;
+import annotations.VTPA;
+import annotations.VTUA;
+import annotations.VVA;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class which, compiled with the JDK 1.8.0, produces the new class file structures from that
+ * version (compared to JDK 1.3.0). Must be compiled with "javac -g -parameters".
+ */
+@VTA(v = 0)
+@ITA(v = 1)
+public abstract class AllStructures<
+ @VTPA(v = 2) @ITPA(v = 3) U0,
+ @VTPA(v = 4) @ITPA(v = 5) U1 extends @VTUA(v = 6) @ITUA(v = 7) List<U0>,
+ @VTPA(v = 8) @ITPA(v = 9)
+ U2 extends @VTUA(v = 10) @ITUA(v = 11) Collection<@VTUA(v = 12) @ITUA(v = 13) U0>>
+ extends @VTUA(v = 14) @ITUA(v = 15) HashMap<
+ @VTUA(v = 16) @ITUA(v = 17) U0, @VTUA(v = 18) @ITUA(v = 19) U1>
+ implements @VTUA(v = 20) @ITUA(v = 21) Callable<@VTUA(v = 22) @ITUA(v = 23) U0>,
+ @VTUA(v = 24) @ITUA(v = 25) Future<@VTUA(v = 26) @ITUA(v = 27) U1> {
+
+ @VFA(v = 28)
+ @IFA(v = 29)
+ public HashMap<@VTUA(v = 30) @ITUA(v = 31) U0, @VTUA(v = 32) @ITUA(v = 33) U1> f;
+
+ @VCA(v = 34)
+ @ICA(v = 35)
+ public AllStructures() {}
+
+ @VMA(v = 36)
+ @IMA(v = 37)
+ public <
+ @VTPA(v = 38) @ITPA(v = 39) V0 extends @VTUA(v = 40) @ITUA(v = 41) U0,
+ @VTUA(v = 42) @ITUA(v = 43) V1 extends @VTUA(v = 44) @ITUA(v = 45) U1>
+ @VTUA(v = 46) @ITUA(v = 47)
+ Map<@VTUA(v = 48) @ITUA(v = 49) ? extends V0, @VTUA(v = 50) @ITUA(v = 51) ? extends V1> m(
+ @VPA(v = 52) @IPA(v = 53) V0 p0,
+ @VPA(v = 54) @IPA(v = 55) V1 p1,
+ @VPA(v = 56) @IPA(v = 57)
+ Map<
+ @VTUA(v = 58) @ITUA(v = 59) ? extends V0, @VTUA(v = 60) @ITUA(v = 61)
+ ? extends V1>
+ p2)
+ throws @VTUA(v = 62) @ITUA(v = 63) IllegalStateException, @VTUA(v = 64) @ITUA(v = 65)
+ IllegalArgumentException {
+ @VVA(v = 66)
+ @IVA(v = 67)
+ V1 l1 = p1;
+ @VVA(v = 68)
+ @IVA(v = 69)
+ Map<@VTUA(v = 70) @ITUA(v = 71) ? extends V0, @VTUA(v = 72) @ITUA(v = 73) ? extends V1> l2 = p2;
+ @VVA(v = 74)
+ @IVA(v = 75)
+ ArrayList l3 = (@VTUA(v = 76) @ITUA(v = 77) ArrayList) l1;
+ try {
+ m(p0, p1, p2);
+ } catch (@VTUA(v = 78) @ITUA(v = 79)
+ IllegalStateException
+ | @VTUA(v = 80) @ITUA(v = 81) IllegalArgumentException e1) {
+ // empty catch block
+ }
+ if (l2 instanceof @VTUA(v = 82) @ITUA(v = 83) HashMap) {
+ return l2;
+ }
+ AllStructures.<@VTUA(v = 84) V0, @ITUA(v = 85) V1>m();
+ return new @VTUA(v = 86) @ITUA(v = 87) HashMap<@VTUA(v = 88) V0, @ITUA(v = 89) V1>();
+ }
+
+ private static <U, V> void m() {}
+
+ private double g;
+
+ private double n() {
+ return g;
+ }
+
+ private Runnable anonymousInnerClass() throws Exception {
+ return new Runnable() {
+ public void run() {
+ @VTUA(v = 0)
+ @ITUA(v = 1)
+ double f = new InnerClass(g + n()).f;
+ new InnerClass(f);
+ }
+ };
+ }
+
+ private class InnerClass {
+
+ @VTUA(v = 0)
+ @ITUA(v = 1)
+ private final double f;
+
+ private InnerClass(double f) {
+ this.f = f;
+ }
+ }
+
+ private class 𝔻 {}
+}
diff --git a/asm-test/src/resources/java/jdk8/DumpArtificialStructures.java b/asm-test/src/resources/java/jdk8/DumpArtificialStructures.java
new file mode 100644
index 00000000..99e45a10
--- /dev/null
+++ b/asm-test/src/resources/java/jdk8/DumpArtificialStructures.java
@@ -0,0 +1,132 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk8;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Generates a class with structures, instructions and patterns that cannot be produced by compiling
+ * a Java source file with the javac compiler. This includes LDC instructions with MethodType
+ * constants.
+ *
+ * <p>Ideally we should not use ASM to generate this class (which is later used to test ASM), but
+ * this would be hard to do.
+ *
+ * @author Eric Bruneton
+ */
+public class DumpArtificialStructures implements Opcodes {
+
+ public static void main(String[] args) throws IOException {
+ FileOutputStream fileOutputStream = new FileOutputStream("Artificial$()$Structures.class");
+ fileOutputStream.write(dump());
+ fileOutputStream.close();
+ }
+
+ private static byte[] dump() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ MethodVisitor methodVisitor;
+
+ classWriter.visit(
+ V1_8,
+ ACC_PUBLIC + ACC_SUPER,
+ "jdk8/Artificial$()$Structures",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitField(ACC_PUBLIC, "value", "I", null, null).visitEnd();
+
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "(I)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitFieldInsn(PUTFIELD, "jdk8/Artificial$()$Structures", "value", "I");
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE, "<init>", "(Ljdk8/Artificial$()$Structures;)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ Label elseLabel = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, elseLabel);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitFieldInsn(GETFIELD, "jdk8/Artificial$()$Structures", "value", "I");
+ Label endIfLabel = new Label();
+ methodVisitor.visitJumpInsn(GOTO, endIfLabel);
+ methodVisitor.visitLabel(elseLabel);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitLabel(endIfLabel);
+ methodVisitor.visitFieldInsn(PUTFIELD, "jdk8/Artificial$()$Structures", "value", "I");
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC, "clone", "()Ljdk8/Artificial$()$Structures;", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitTypeInsn(NEW, "jdk8/Artificial$()$Structures");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL,
+ "jdk8/Artificial$()$Structures",
+ "<init>",
+ "(Ljdk8/Artificial$()$Structures;)V",
+ false);
+ methodVisitor.visitInsn(ARETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC + ACC_STATIC, "methodType", "()Ljava/lang/invoke/MethodType;", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitLdcInsn(Type.getMethodType("(I)I"));
+ methodVisitor.visitInsn(ARETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ classWriter.visitEnd();
+ return classWriter.toByteArray();
+ }
+}
diff --git a/asm-test/src/resources/java/jdk8/LargeMethod.java b/asm-test/src/resources/java/jdk8/LargeMethod.java
new file mode 100644
index 00000000..b23a6c1b
--- /dev/null
+++ b/asm-test/src/resources/java/jdk8/LargeMethod.java
@@ -0,0 +1,400 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package jdk8;
+
+/**
+ * Class which, compiled with the JDK 1.8.0, produces a large method with stack map frames. Must be
+ * compiled with "javac -g -parameters".
+ */
+public class LargeMethod {
+
+ int f;
+
+ public LargeMethod(Object o, String s) {}
+
+ // Frames in methods larger than 32K.
+ public LargeMethod largeMethod(
+ boolean v0,
+ byte v1,
+ char v2,
+ short v3,
+ int v4,
+ long v5,
+ float v6,
+ double v7,
+ Object v8,
+ boolean[] v9,
+ byte[] v10,
+ char[] v11,
+ short[] v12,
+ int[] v13,
+ long[] v14,
+ float[] v15,
+ double[] v16,
+ Object[] v17) {
+ try {
+ while (v4++ < v5) {
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ f =
+ f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f + f
+ + f + f + f + f + f + f + f + f;
+ }
+ } catch (Throwable t) {
+ return null;
+ } finally {
+ v17[0] = null;
+ }
+ return new LargeMethod(v17[f % v17.length], null);
+ }
+}
diff --git a/asm-test/src/resources/java/jdk9/META-INF/MANIFEST.MF b/asm-test/src/resources/java/jdk9/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..e2ce4c2e
--- /dev/null
+++ b/asm-test/src/resources/java/jdk9/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Created-By: 9 (Oracle Corporation)
+Main-Class: pkg.A
+
diff --git a/asm-test/src/resources/java/jdk9/pkg/module-info.java b/asm-test/src/resources/java/jdk9/pkg/module-info.java
new file mode 100644
index 00000000..60a07ae9
--- /dev/null
+++ b/asm-test/src/resources/java/jdk9/pkg/module-info.java
@@ -0,0 +1,43 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * Class which, compiled with the JDK 1.9.0, produces the new ModuleInfo
+ * attribute in this version.
+ */
+module pkg {
+ requires java.compiler;
+ requires static java.naming;
+ requires transitive java.prefs;
+ exports pkg to java.compiler, java.naming;
+ exports pkg.internal to java.prefs;
+ opens pkg.internal to pkg, java.naming;
+ uses pkg.A;
+ uses java.lang.Integer;
+ provides pkg.A with pkg.internal.AImpl;
+}
diff --git a/asm-test/src/resources/java/jdk9/pkg/pkg/A.java b/asm-test/src/resources/java/jdk9/pkg/pkg/A.java
new file mode 100644
index 00000000..90008c6e
--- /dev/null
+++ b/asm-test/src/resources/java/jdk9/pkg/pkg/A.java
@@ -0,0 +1,34 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package pkg;
+
+/** Dummy "service" class to define a basic moduleinfo. */
+public class A {
+
+ public static void main(String[] args) {}
+}
diff --git a/asm-test/src/resources/java/jdk9/pkg/pkg/internal/AImpl.java b/asm-test/src/resources/java/jdk9/pkg/pkg/internal/AImpl.java
new file mode 100644
index 00000000..8da50d63
--- /dev/null
+++ b/asm-test/src/resources/java/jdk9/pkg/pkg/internal/AImpl.java
@@ -0,0 +1,31 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package pkg.internal;
+
+/** Dummy "service implementation" class to define a basic moduleinfo. */
+public class AImpl extends pkg.A {}
diff --git a/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java
new file mode 100644
index 00000000..d8645487
--- /dev/null
+++ b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java
@@ -0,0 +1,110 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.provider.Arguments;
+
+/**
+ * Unit tests for {@link AsmTest}.
+ *
+ * @author Eric Bruneton
+ */
+class AsmTestTest extends AsmTest {
+
+ @Test
+ void testPrecompiledClass_allMethods() {
+ assertEquals("jdk3.AllInstructions", PrecompiledClass.JDK3_ALL_INSTRUCTIONS.getName());
+ assertEquals("jdk8/AllInstructions", PrecompiledClass.JDK8_ALL_INSTRUCTIONS.getInternalName());
+ assertEquals("module-info", PrecompiledClass.JDK9_MODULE.getInternalName());
+ assertFalse(PrecompiledClass.JDK3_ALL_INSTRUCTIONS.isMoreRecentThan(Api.ASM4));
+ assertTrue(PrecompiledClass.JDK8_ALL_INSTRUCTIONS.isMoreRecentThan(Api.ASM4));
+ assertFalse(PrecompiledClass.JDK8_ALL_INSTRUCTIONS.isMoreRecentThan(Api.ASM5));
+ assertTrue(PrecompiledClass.JDK9_MODULE.isMoreRecentThan(Api.ASM5));
+ assertFalse(PrecompiledClass.JDK9_MODULE.isMoreRecentThan(Api.ASM6));
+ assertTrue(PrecompiledClass.JDK11_ALL_INSTRUCTIONS.isMoreRecentThan(Api.ASM6));
+ assertFalse(PrecompiledClass.JDK11_ALL_INSTRUCTIONS.isMoreRecentThan(Api.ASM7));
+ assertNotNull(PrecompiledClass.JDK11_ALL_INSTRUCTIONS.getBytes());
+ assertEquals("jdk11.AllInstructions", PrecompiledClass.JDK11_ALL_INSTRUCTIONS.toString());
+ assertTrue(PrecompiledClass.JDK14_ALL_STRUCTURES_RECORD.isMoreRecentThan(Api.ASM7));
+ assertFalse(PrecompiledClass.JDK14_ALL_STRUCTURES_RECORD.isMoreRecentThan(Api.ASM8));
+ assertTrue(PrecompiledClass.JDK14_ALL_STRUCTURES_EMPTY_RECORD.isMoreRecentThan(Api.ASM7));
+ assertFalse(PrecompiledClass.JDK14_ALL_STRUCTURES_EMPTY_RECORD.isMoreRecentThan(Api.ASM8));
+ assertTrue(PrecompiledClass.JDK15_ALL_STRUCTURES.isMoreRecentThan(Api.ASM8));
+ assertFalse(PrecompiledClass.JDK15_ALL_STRUCTURES.isMoreRecentThan(Api.ASM9));
+ }
+
+ @Test
+ void testInvalidClass_allMethods() {
+ InvalidClass invalidBytecodeOffset = InvalidClass.INVALID_BYTECODE_OFFSET;
+
+ assertNotNull(invalidBytecodeOffset.getBytes());
+ assertEquals("invalid.InvalidBytecodeOffset", invalidBytecodeOffset.toString());
+ }
+
+ @Test
+ void testApi_allMethods() {
+ Api asm7 = Api.ASM7;
+
+ assertEquals(0x70000, asm7.value());
+ assertEquals("ASM7", asm7.toString());
+ }
+
+ @Test
+ void testGetAllClassesAndAllApis() {
+ List<Arguments> allArguments = allClassesAndAllApis().collect(Collectors.toList());
+
+ assertEquals(
+ new HashSet<Object>(Arrays.asList(PrecompiledClass.values())),
+ allArguments.stream().map(arg -> arg.get()[0]).collect(Collectors.toSet()));
+ assertEquals(
+ new HashSet<Object>(Arrays.asList(Api.values())),
+ allArguments.stream().map(arg -> arg.get()[1]).collect(Collectors.toSet()));
+ }
+
+ @Test
+ void testGetAllClassesAndLatestApi() {
+ List<Arguments> allArguments = allClassesAndLatestApi().collect(Collectors.toList());
+
+ assertEquals(
+ new HashSet<Object>(Arrays.asList(PrecompiledClass.values())),
+ allArguments.stream().map(arg -> arg.get()[0]).collect(Collectors.toSet()));
+ assertEquals(
+ new HashSet<Object>(Arrays.asList(Api.ASM9)),
+ allArguments.stream().map(arg -> arg.get()[1]).collect(Collectors.toSet()));
+ }
+}
diff --git a/asm-test/src/test/java/org/objectweb/asm/test/ClassFileTest.java b/asm-test/src/test/java/org/objectweb/asm/test/ClassFileTest.java
new file mode 100644
index 00000000..e2e2a13b
--- /dev/null
+++ b/asm-test/src/test/java/org/objectweb/asm/test/ClassFileTest.java
@@ -0,0 +1,152 @@
+package org.objectweb.asm.test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Unit tests for {@link ClassFile}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassFileTest extends AsmTest {
+
+ @Test
+ void testGetConstantPoolDump() {
+ ClassFile classFile = new ClassFile(PrecompiledClass.JDK3_ALL_INSTRUCTIONS.getBytes());
+
+ String constantPoolDump = classFile.getConstantPoolDump();
+
+ assertTrue(constantPoolDump.contains("constant_pool: ConstantClassInfo jdk3/AllInstructions"));
+ }
+
+ /** Tests that newInstance() succeeds for each precompiled class. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testNewInstance_validClass(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassFile classFile = new ClassFile(classParameter.getBytes());
+
+ Executable newInstance = () -> classFile.newInstance();
+
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+
+ /** Tests that newInstance() fails when trying to load an invalid or unverifiable class. */
+ @ParameterizedTest
+ @EnumSource(InvalidClass.class)
+ void testNewInstance_invalidClass(final InvalidClass invalidClass) {
+ ClassFile classFile = new ClassFile(invalidClass.getBytes());
+
+ Executable newInstance = () -> classFile.newInstance();
+
+ assertThrows(ClassFormatException.class, newInstance);
+ }
+
+ /**
+ * Tests that the static newInstance() method fails when trying to load an invalid or unverifiable
+ * class.
+ */
+ @ParameterizedTest
+ @EnumSource(InvalidClass.class)
+ void testStaticNewInstance_invalidClass(final InvalidClass invalidClass) {
+ String className = invalidClass.toString();
+ byte[] classContent = invalidClass.getBytes();
+
+ Executable newInstance = () -> ClassFile.newInstance(className, classContent);
+
+ switch (invalidClass) {
+ case INVALID_ELEMENT_VALUE:
+ case INVALID_TYPE_ANNOTATION_TARGET_TYPE:
+ case INVALID_INSN_TYPE_ANNOTATION_TARGET_TYPE:
+ break;
+ case INVALID_BYTECODE_OFFSET:
+ case INVALID_OPCODE:
+ case INVALID_WIDE_OPCODE:
+ assertThrows(VerifyError.class, newInstance);
+ break;
+ case INVALID_CLASS_VERSION:
+ case INVALID_CODE_LENGTH:
+ case INVALID_CONSTANT_POOL_INDEX:
+ case INVALID_CONSTANT_POOL_REFERENCE:
+ case INVALID_CP_INFO_TAG:
+ case INVALID_SOURCE_DEBUG_EXTENSION:
+ case INVALID_STACK_MAP_FRAME_TYPE:
+ case INVALID_VERIFICATION_TYPE_INFO:
+ assertThrows(ClassFormatError.class, newInstance);
+ break;
+ default:
+ fail("Unknown invalid class");
+ break;
+ }
+ }
+
+ @Test
+ void testEquals() {
+ ClassFile classFile1 = new ClassFile(PrecompiledClass.JDK3_ALL_INSTRUCTIONS.getBytes());
+ ClassFile classFile2 = new ClassFile(PrecompiledClass.JDK5_ALL_INSTRUCTIONS.getBytes());
+
+ boolean equalsThis = classFile1.equals(classFile1);
+ boolean equalsDifferentClass = classFile1.equals(classFile2);
+ boolean equalsInvalidClass = classFile1.equals(new byte[0]);
+
+ assertTrue(equalsThis);
+ assertFalse(equalsDifferentClass);
+ assertFalse(equalsInvalidClass);
+ }
+
+ @Test
+ void testHashcode_validClass() {
+ PrecompiledClass precompiledClass = PrecompiledClass.JDK3_ALL_INSTRUCTIONS;
+ ClassFile classFile = new ClassFile(precompiledClass.getBytes());
+
+ int hashCode = classFile.hashCode();
+
+ assertNotEquals(0, hashCode);
+ }
+
+ @Test
+ void testHashcode_invalidClass() {
+ InvalidClass invalidClass = InvalidClass.INVALID_CLASS_VERSION;
+ ClassFile classFile = new ClassFile(invalidClass.getBytes());
+
+ Executable hashCode = () -> classFile.hashCode();
+
+ Exception exception = assertThrows(ClassFormatException.class, hashCode);
+ assertEquals("Unsupported class version", exception.getMessage());
+ }
+
+ @Test
+ void testToString_validClass() {
+ PrecompiledClass precompiledClass = PrecompiledClass.JDK3_ALL_INSTRUCTIONS;
+ ClassFile classFile = new ClassFile(precompiledClass.getBytes());
+
+ String classString = classFile.toString();
+
+ assertTrue(classString.contains(precompiledClass.getInternalName()));
+ }
+
+ @Test
+ void testToString_invalidClass() {
+ InvalidClass invalidClass = InvalidClass.INVALID_CLASS_VERSION;
+ ClassFile classFile = new ClassFile(invalidClass.getBytes());
+
+ Executable toString = () -> classFile.toString();
+
+ Exception exception = assertThrows(ClassFormatException.class, toString);
+ assertEquals("Unsupported class version", exception.getMessage());
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/AbstractInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/AbstractInsnNode.java
new file mode 100644
index 00000000..83d0682a
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/AbstractInsnNode.java
@@ -0,0 +1,269 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a bytecode instruction. <i>An instruction can appear at most once in at
+ * most one {@link InsnList} at a time</i>.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AbstractInsnNode {
+
+ /** The type of {@link InsnNode} instructions. */
+ public static final int INSN = 0;
+
+ /** The type of {@link IntInsnNode} instructions. */
+ public static final int INT_INSN = 1;
+
+ /** The type of {@link VarInsnNode} instructions. */
+ public static final int VAR_INSN = 2;
+
+ /** The type of {@link TypeInsnNode} instructions. */
+ public static final int TYPE_INSN = 3;
+
+ /** The type of {@link FieldInsnNode} instructions. */
+ public static final int FIELD_INSN = 4;
+
+ /** The type of {@link MethodInsnNode} instructions. */
+ public static final int METHOD_INSN = 5;
+
+ /** The type of {@link InvokeDynamicInsnNode} instructions. */
+ public static final int INVOKE_DYNAMIC_INSN = 6;
+
+ /** The type of {@link JumpInsnNode} instructions. */
+ public static final int JUMP_INSN = 7;
+
+ /** The type of {@link LabelNode} "instructions". */
+ public static final int LABEL = 8;
+
+ /** The type of {@link LdcInsnNode} instructions. */
+ public static final int LDC_INSN = 9;
+
+ /** The type of {@link IincInsnNode} instructions. */
+ public static final int IINC_INSN = 10;
+
+ /** The type of {@link TableSwitchInsnNode} instructions. */
+ public static final int TABLESWITCH_INSN = 11;
+
+ /** The type of {@link LookupSwitchInsnNode} instructions. */
+ public static final int LOOKUPSWITCH_INSN = 12;
+
+ /** The type of {@link MultiANewArrayInsnNode} instructions. */
+ public static final int MULTIANEWARRAY_INSN = 13;
+
+ /** The type of {@link FrameNode} "instructions". */
+ public static final int FRAME = 14;
+
+ /** The type of {@link LineNumberNode} "instructions". */
+ public static final int LINE = 15;
+
+ /**
+ * The opcode of this instruction, or -1 if this is not a JVM instruction (e.g. a label or a line
+ * number).
+ */
+ protected int opcode;
+
+ /**
+ * The runtime visible type annotations of this instruction. This field is only used for real
+ * instructions (i.e. not for labels, frames, or line number nodes). This list is a list of {@link
+ * TypeAnnotationNode} objects. May be {@literal null}.
+ */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /**
+ * The runtime invisible type annotations of this instruction. This field is only used for real
+ * instructions (i.e. not for labels, frames, or line number nodes). This list is a list of {@link
+ * TypeAnnotationNode} objects. May be {@literal null}.
+ */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /** The previous instruction in the list to which this instruction belongs. */
+ AbstractInsnNode previousInsn;
+
+ /** The next instruction in the list to which this instruction belongs. */
+ AbstractInsnNode nextInsn;
+
+ /**
+ * The index of this instruction in the list to which it belongs. The value of this field is
+ * correct only when {@link InsnList#cache} is not null. A value of -1 indicates that this
+ * instruction does not belong to any {@link InsnList}.
+ */
+ int index;
+
+ /**
+ * Constructs a new {@link AbstractInsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed.
+ */
+ protected AbstractInsnNode(final int opcode) {
+ this.opcode = opcode;
+ this.index = -1;
+ }
+
+ /**
+ * Returns the opcode of this instruction.
+ *
+ * @return the opcode of this instruction, or -1 if this is not a JVM instruction (e.g. a label or
+ * a line number).
+ */
+ public int getOpcode() {
+ return opcode;
+ }
+
+ /**
+ * Returns the type of this instruction.
+ *
+ * @return the type of this instruction, i.e. one the constants defined in this class.
+ */
+ public abstract int getType();
+
+ /**
+ * Returns the previous instruction in the list to which this instruction belongs, if any.
+ *
+ * @return the previous instruction in the list to which this instruction belongs, if any. May be
+ * {@literal null}.
+ */
+ public AbstractInsnNode getPrevious() {
+ return previousInsn;
+ }
+
+ /**
+ * Returns the next instruction in the list to which this instruction belongs, if any.
+ *
+ * @return the next instruction in the list to which this instruction belongs, if any. May be
+ * {@literal null}.
+ */
+ public AbstractInsnNode getNext() {
+ return nextInsn;
+ }
+
+ /**
+ * Makes the given method visitor visit this instruction.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ public abstract void accept(MethodVisitor methodVisitor);
+
+ /**
+ * Makes the given visitor visit the annotations of this instruction.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ protected final void acceptAnnotations(final MethodVisitor methodVisitor) {
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitInsnAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitInsnAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ }
+
+ /**
+ * Returns a copy of this instruction.
+ *
+ * @param clonedLabels a map from LabelNodes to cloned LabelNodes.
+ * @return a copy of this instruction. The returned instruction does not belong to any {@link
+ * InsnList}.
+ */
+ public abstract AbstractInsnNode clone(Map<LabelNode, LabelNode> clonedLabels);
+
+ /**
+ * Returns the clone of the given label.
+ *
+ * @param label a label.
+ * @param clonedLabels a map from LabelNodes to cloned LabelNodes.
+ * @return the clone of the given label.
+ */
+ static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> clonedLabels) {
+ return clonedLabels.get(label);
+ }
+
+ /**
+ * Returns the clones of the given labels.
+ *
+ * @param labels a list of labels.
+ * @param clonedLabels a map from LabelNodes to cloned LabelNodes.
+ * @return the clones of the given labels.
+ */
+ static LabelNode[] clone(
+ final List<LabelNode> labels, final Map<LabelNode, LabelNode> clonedLabels) {
+ LabelNode[] clones = new LabelNode[labels.size()];
+ for (int i = 0, n = clones.length; i < n; ++i) {
+ clones[i] = clonedLabels.get(labels.get(i));
+ }
+ return clones;
+ }
+
+ /**
+ * Clones the annotations of the given instruction into this instruction.
+ *
+ * @param insnNode the source instruction.
+ * @return this instruction.
+ */
+ protected final AbstractInsnNode cloneAnnotations(final AbstractInsnNode insnNode) {
+ if (insnNode.visibleTypeAnnotations != null) {
+ this.visibleTypeAnnotations = new ArrayList<>();
+ for (int i = 0, n = insnNode.visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode sourceAnnotation = insnNode.visibleTypeAnnotations.get(i);
+ TypeAnnotationNode cloneAnnotation =
+ new TypeAnnotationNode(
+ sourceAnnotation.typeRef, sourceAnnotation.typePath, sourceAnnotation.desc);
+ sourceAnnotation.accept(cloneAnnotation);
+ this.visibleTypeAnnotations.add(cloneAnnotation);
+ }
+ }
+ if (insnNode.invisibleTypeAnnotations != null) {
+ this.invisibleTypeAnnotations = new ArrayList<>();
+ for (int i = 0, n = insnNode.invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode sourceAnnotation = insnNode.invisibleTypeAnnotations.get(i);
+ TypeAnnotationNode cloneAnnotation =
+ new TypeAnnotationNode(
+ sourceAnnotation.typeRef, sourceAnnotation.typePath, sourceAnnotation.desc);
+ sourceAnnotation.accept(cloneAnnotation);
+ this.invisibleTypeAnnotations.add(cloneAnnotation);
+ }
+ }
+ return this;
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java
new file mode 100644
index 00000000..56558473
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java
@@ -0,0 +1,230 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents an annotation.
+ *
+ * @author Eric Bruneton
+ */
+public class AnnotationNode extends AnnotationVisitor {
+
+ /** The class descriptor of the annotation class. */
+ public String desc;
+
+ /**
+ * The name value pairs of this annotation. Each name value pair is stored as two consecutive
+ * elements in the list. The name is a {@link String}, and the value may be a {@link Byte}, {@link
+ * Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link Float},
+ * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or a two elements String
+ * array (for enumeration values), an {@link AnnotationNode}, or a {@link List} of values of one
+ * of the preceding types. The list may be {@literal null} if there is no name value pair.
+ */
+ public List<Object> values;
+
+ /**
+ * Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #AnnotationNode(int, String)} version.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public AnnotationNode(final String descriptor) {
+ this(/* latest api = */ Opcodes.ASM9, descriptor);
+ if (getClass() != AnnotationNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link AnnotationNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param descriptor the class descriptor of the annotation class.
+ */
+ public AnnotationNode(final int api, final String descriptor) {
+ super(api);
+ this.desc = descriptor;
+ }
+
+ /**
+ * Constructs a new {@link AnnotationNode} to visit an array value.
+ *
+ * @param values where the visited values must be stored.
+ */
+ AnnotationNode(final List<Object> values) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.values = values;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor abstract class
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visit(final String name, final Object value) {
+ if (values == null) {
+ values = new ArrayList<>(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ if (value instanceof byte[]) {
+ values.add(Util.asArrayList((byte[]) value));
+ } else if (value instanceof boolean[]) {
+ values.add(Util.asArrayList((boolean[]) value));
+ } else if (value instanceof short[]) {
+ values.add(Util.asArrayList((short[]) value));
+ } else if (value instanceof char[]) {
+ values.add(Util.asArrayList((char[]) value));
+ } else if (value instanceof int[]) {
+ values.add(Util.asArrayList((int[]) value));
+ } else if (value instanceof long[]) {
+ values.add(Util.asArrayList((long[]) value));
+ } else if (value instanceof float[]) {
+ values.add(Util.asArrayList((float[]) value));
+ } else if (value instanceof double[]) {
+ values.add(Util.asArrayList((double[]) value));
+ } else {
+ values.add(value);
+ }
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ if (values == null) {
+ values = new ArrayList<>(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ values.add(new String[] {descriptor, value});
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ if (values == null) {
+ values = new ArrayList<>(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ values.add(annotation);
+ return annotation;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ if (values == null) {
+ values = new ArrayList<>(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ List<Object> array = new ArrayList<>();
+ values.add(array);
+ return new AnnotationNode(array);
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // ------------------------------------------------------------------------
+ // Accept methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Checks that this annotation node is compatible with the given ASM API version. This method
+ * checks that this node, and all its children recursively, do not contain elements that were
+ * introduced in more recent versions of the ASM API than the given version.
+ *
+ * @param api an ASM API version. Must be one of the {@code ASM}<i>x</i> values in {@link
+ * Opcodes}.
+ */
+ public void check(final int api) {
+ // nothing to do
+ }
+
+ /**
+ * Makes the given visitor visit this annotation.
+ *
+ * @param annotationVisitor an annotation visitor. Maybe {@literal null}.
+ */
+ public void accept(final AnnotationVisitor annotationVisitor) {
+ if (annotationVisitor != null) {
+ if (values != null) {
+ for (int i = 0, n = values.size(); i < n; i += 2) {
+ String name = (String) values.get(i);
+ Object value = values.get(i + 1);
+ accept(annotationVisitor, name, value);
+ }
+ }
+ annotationVisitor.visitEnd();
+ }
+ }
+
+ /**
+ * Makes the given visitor visit a given annotation value.
+ *
+ * @param annotationVisitor an annotation visitor. Maybe {@literal null}.
+ * @param name the value name.
+ * @param value the actual value.
+ */
+ static void accept(
+ final AnnotationVisitor annotationVisitor, final String name, final Object value) {
+ if (annotationVisitor != null) {
+ if (value instanceof String[]) {
+ String[] typeValue = (String[]) value;
+ annotationVisitor.visitEnum(name, typeValue[0], typeValue[1]);
+ } else if (value instanceof AnnotationNode) {
+ AnnotationNode annotationValue = (AnnotationNode) value;
+ annotationValue.accept(annotationVisitor.visitAnnotation(name, annotationValue.desc));
+ } else if (value instanceof List) {
+ AnnotationVisitor arrayAnnotationVisitor = annotationVisitor.visitArray(name);
+ if (arrayAnnotationVisitor != null) {
+ List<?> arrayValue = (List<?>) value;
+ for (int i = 0, n = arrayValue.size(); i < n; ++i) {
+ accept(arrayAnnotationVisitor, null, arrayValue.get(i));
+ }
+ arrayAnnotationVisitor.visitEnd();
+ }
+ } else {
+ annotationVisitor.visit(name, value);
+ }
+ }
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java
new file mode 100644
index 00000000..bd43dc71
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java
@@ -0,0 +1,472 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a class.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassNode extends ClassVisitor {
+
+ /**
+ * The class version. The minor version is stored in the 16 most significant bits, and the major
+ * version in the 16 least significant bits.
+ */
+ public int version;
+
+ /**
+ * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates if
+ * the class is deprecated {@link Opcodes#ACC_DEPRECATED} or a record {@link Opcodes#ACC_RECORD}.
+ */
+ public int access;
+
+ /** The internal name of this class (see {@link org.objectweb.asm.Type#getInternalName()}). */
+ public String name;
+
+ /** The signature of this class. May be {@literal null}. */
+ public String signature;
+
+ /**
+ * The internal of name of the super class (see {@link org.objectweb.asm.Type#getInternalName()}).
+ * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the
+ * {@link Object} class.
+ */
+ public String superName;
+
+ /**
+ * The internal names of the interfaces directly implemented by this class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ */
+ public List<String> interfaces;
+
+ /** The name of the source file from which this class was compiled. May be {@literal null}. */
+ public String sourceFile;
+
+ /**
+ * The correspondence between source and compiled elements of this class. May be {@literal null}.
+ */
+ public String sourceDebug;
+
+ /** The module stored in this class. May be {@literal null}. */
+ public ModuleNode module;
+
+ /**
+ * The internal name of the enclosing class of this class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). Must be {@literal null} if this class has no
+ * enclosing class, or if it is a local or anonymous class.
+ */
+ public String outerClass;
+
+ /**
+ * The name of the method that contains the class, or {@literal null} if the class has no
+ * enclosing class, or is not enclosed in a method or constructor of its enclosing class (e.g. if
+ * it is enclosed in an instance initializer, static initializer, instance variable initializer,
+ * or class variable initializer).
+ */
+ public String outerMethod;
+
+ /**
+ * The descriptor of the method that contains the class, or {@literal null} if the class has no
+ * enclosing class, or is not enclosed in a method or constructor of its enclosing class (e.g. if
+ * it is enclosed in an instance initializer, static initializer, instance variable initializer,
+ * or class variable initializer).
+ */
+ public String outerMethodDesc;
+
+ /** The runtime visible annotations of this class. May be {@literal null}. */
+ public List<AnnotationNode> visibleAnnotations;
+
+ /** The runtime invisible annotations of this class. May be {@literal null}. */
+ public List<AnnotationNode> invisibleAnnotations;
+
+ /** The runtime visible type annotations of this class. May be {@literal null}. */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /** The runtime invisible type annotations of this class. May be {@literal null}. */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /** The non standard attributes of this class. May be {@literal null}. */
+ public List<Attribute> attrs;
+
+ /** The inner classes of this class. */
+ public List<InnerClassNode> innerClasses;
+
+ /**
+ * The internal name of the nest host class of this class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public String nestHostClass;
+
+ /**
+ * The internal names of the nest members of this class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public List<String> nestMembers;
+
+ /**
+ * The internal names of the permitted subclasses of this class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public List<String> permittedSubclasses;
+
+ /** The record components of this class. May be {@literal null}. */
+ public List<RecordComponentNode> recordComponents;
+
+ /** The fields of this class. */
+ public List<FieldNode> fields;
+
+ /** The methods of this class. */
+ public List<MethodNode> methods;
+
+ /**
+ * Constructs a new {@link ClassNode}. <i>Subclasses must not use this constructor</i>. Instead,
+ * they must use the {@link #ClassNode(int)} version.
+ *
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public ClassNode() {
+ this(Opcodes.ASM9);
+ if (getClass() != ClassNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link ClassNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ public ClassNode(final int api) {
+ super(api);
+ this.interfaces = new ArrayList<>();
+ this.innerClasses = new ArrayList<>();
+ this.fields = new ArrayList<>();
+ this.methods = new ArrayList<>();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the ClassVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ this.version = version;
+ this.access = access;
+ this.name = name;
+ this.signature = signature;
+ this.superName = superName;
+ this.interfaces = Util.asArrayList(interfaces);
+ }
+
+ @Override
+ public void visitSource(final String file, final String debug) {
+ sourceFile = file;
+ sourceDebug = debug;
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ module = new ModuleNode(name, access, version);
+ return module;
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ this.nestHostClass = nestHost;
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ outerClass = owner;
+ outerMethod = name;
+ outerMethodDesc = descriptor;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ if (visible) {
+ visibleAnnotations = Util.add(visibleAnnotations, annotation);
+ } else {
+ invisibleAnnotations = Util.add(invisibleAnnotations, annotation);
+ }
+ return annotation;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ visibleTypeAnnotations = Util.add(visibleTypeAnnotations, typeAnnotation);
+ } else {
+ invisibleTypeAnnotations = Util.add(invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ attrs = Util.add(attrs, attribute);
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ nestMembers = Util.add(nestMembers, nestMember);
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ permittedSubclasses = Util.add(permittedSubclasses, permittedSubclass);
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ InnerClassNode innerClass = new InnerClassNode(name, outerName, innerName, access);
+ innerClasses.add(innerClass);
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ RecordComponentNode recordComponent = new RecordComponentNode(name, descriptor, signature);
+ recordComponents = Util.add(recordComponents, recordComponent);
+ return recordComponent;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ FieldNode field = new FieldNode(access, name, descriptor, signature, value);
+ fields.add(field);
+ return field;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodNode method = new MethodNode(access, name, descriptor, signature, exceptions);
+ methods.add(method);
+ return method;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accept method
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Checks that this class node is compatible with the given ASM API version. This method checks
+ * that this node, and all its children recursively, do not contain elements that were introduced
+ * in more recent versions of the ASM API than the given version.
+ *
+ * @param api an ASM API version. Must be one of the {@code ASM}<i>x</i> values in {@link
+ * Opcodes}.
+ */
+ public void check(final int api) {
+ if (api < Opcodes.ASM9 && permittedSubclasses != null) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (api < Opcodes.ASM8 && ((access & Opcodes.ACC_RECORD) != 0 || recordComponents != null)) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (api < Opcodes.ASM7 && (nestHostClass != null || nestMembers != null)) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (api < Opcodes.ASM6 && module != null) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (api < Opcodes.ASM5) {
+ if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ // Check the annotations.
+ if (visibleAnnotations != null) {
+ for (int i = visibleAnnotations.size() - 1; i >= 0; --i) {
+ visibleAnnotations.get(i).check(api);
+ }
+ }
+ if (invisibleAnnotations != null) {
+ for (int i = invisibleAnnotations.size() - 1; i >= 0; --i) {
+ invisibleAnnotations.get(i).check(api);
+ }
+ }
+ if (visibleTypeAnnotations != null) {
+ for (int i = visibleTypeAnnotations.size() - 1; i >= 0; --i) {
+ visibleTypeAnnotations.get(i).check(api);
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = invisibleTypeAnnotations.size() - 1; i >= 0; --i) {
+ invisibleTypeAnnotations.get(i).check(api);
+ }
+ }
+ if (recordComponents != null) {
+ for (int i = recordComponents.size() - 1; i >= 0; --i) {
+ recordComponents.get(i).check(api);
+ }
+ }
+ for (int i = fields.size() - 1; i >= 0; --i) {
+ fields.get(i).check(api);
+ }
+ for (int i = methods.size() - 1; i >= 0; --i) {
+ methods.get(i).check(api);
+ }
+ }
+
+ /**
+ * Makes the given class visitor visit this class.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ // Visit the header.
+ String[] interfacesArray = new String[this.interfaces.size()];
+ this.interfaces.toArray(interfacesArray);
+ classVisitor.visit(version, access, name, signature, superName, interfacesArray);
+ // Visit the source.
+ if (sourceFile != null || sourceDebug != null) {
+ classVisitor.visitSource(sourceFile, sourceDebug);
+ }
+ // Visit the module.
+ if (module != null) {
+ module.accept(classVisitor);
+ }
+ // Visit the nest host class.
+ if (nestHostClass != null) {
+ classVisitor.visitNestHost(nestHostClass);
+ }
+ // Visit the outer class.
+ if (outerClass != null) {
+ classVisitor.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
+ }
+ // Visit the annotations.
+ if (visibleAnnotations != null) {
+ for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = visibleAnnotations.get(i);
+ annotation.accept(classVisitor.visitAnnotation(annotation.desc, true));
+ }
+ }
+ if (invisibleAnnotations != null) {
+ for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = invisibleAnnotations.get(i);
+ annotation.accept(classVisitor.visitAnnotation(annotation.desc, false));
+ }
+ }
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ classVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ classVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ // Visit the non standard attributes.
+ if (attrs != null) {
+ for (int i = 0, n = attrs.size(); i < n; ++i) {
+ classVisitor.visitAttribute(attrs.get(i));
+ }
+ }
+ // Visit the nest members.
+ if (nestMembers != null) {
+ for (int i = 0, n = nestMembers.size(); i < n; ++i) {
+ classVisitor.visitNestMember(nestMembers.get(i));
+ }
+ }
+ // Visit the permitted subclasses.
+ if (permittedSubclasses != null) {
+ for (int i = 0, n = permittedSubclasses.size(); i < n; ++i) {
+ classVisitor.visitPermittedSubclass(permittedSubclasses.get(i));
+ }
+ }
+ // Visit the inner classes.
+ for (int i = 0, n = innerClasses.size(); i < n; ++i) {
+ innerClasses.get(i).accept(classVisitor);
+ }
+ // Visit the record components.
+ if (recordComponents != null) {
+ for (int i = 0, n = recordComponents.size(); i < n; ++i) {
+ recordComponents.get(i).accept(classVisitor);
+ }
+ }
+ // Visit the fields.
+ for (int i = 0, n = fields.size(); i < n; ++i) {
+ fields.get(i).accept(classVisitor);
+ }
+ // Visit the methods.
+ for (int i = 0, n = methods.size(); i < n; ++i) {
+ methods.get(i).accept(classVisitor);
+ }
+ classVisitor.visitEnd();
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/FieldInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldInsnNode.java
new file mode 100644
index 00000000..ed8b1048
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldInsnNode.java
@@ -0,0 +1,96 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a field instruction. A field instruction is an instruction that loads or
+ * stores the value of a field of an object.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldInsnNode extends AbstractInsnNode {
+
+ /**
+ * The internal name of the field's owner class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ */
+ public String owner;
+
+ /** The field's name. */
+ public String name;
+
+ /** The field's descriptor (see {@link org.objectweb.asm.Type}). */
+ public String desc;
+
+ /**
+ * Constructs a new {@link FieldInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This opcode must be
+ * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner the internal name of the field's owner class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link org.objectweb.asm.Type}).
+ */
+ public FieldInsnNode(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super(opcode);
+ this.owner = owner;
+ this.name = name;
+ this.desc = descriptor;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be GETSTATIC, PUTSTATIC, GETFIELD or
+ * PUTFIELD.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return FIELD_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitFieldInsn(opcode, owner, name, desc);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new FieldInsnNode(opcode, owner, name, desc).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java
new file mode 100644
index 00000000..1c30d7fc
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java
@@ -0,0 +1,244 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a field.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldNode extends FieldVisitor {
+
+ /**
+ * The field's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates if
+ * the field is synthetic and/or deprecated.
+ */
+ public int access;
+
+ /** The field's name. */
+ public String name;
+
+ /** The field's descriptor (see {@link org.objectweb.asm.Type}). */
+ public String desc;
+
+ /** The field's signature. May be {@literal null}. */
+ public String signature;
+
+ /**
+ * The field's initial value. This field, which may be {@literal null} if the field does not have
+ * an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}
+ * or a {@link String}.
+ */
+ public Object value;
+
+ /** The runtime visible annotations of this field. May be {@literal null}. */
+ public List<AnnotationNode> visibleAnnotations;
+
+ /** The runtime invisible annotations of this field. May be {@literal null}. */
+ public List<AnnotationNode> invisibleAnnotations;
+
+ /** The runtime visible type annotations of this field. May be {@literal null}. */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /** The runtime invisible type annotations of this field. May be {@literal null}. */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /** The non standard attributes of this field. * May be {@literal null}. */
+ public List<Attribute> attrs;
+
+ /**
+ * Constructs a new {@link FieldNode}. <i>Subclasses must not use this constructor</i>. Instead,
+ * they must use the {@link #FieldNode(int, int, String, String, String, Object)} version.
+ *
+ * @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This parameter
+ * also indicates if the field is synthetic and/or deprecated.
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the field's signature.
+ * @param value the field's initial value. This parameter, which may be {@literal null} if the
+ * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
+ * Long}, a {@link Double} or a {@link String}.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public FieldNode(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ this(/* latest api = */ Opcodes.ASM9, access, name, descriptor, signature, value);
+ if (getClass() != FieldNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link FieldNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This parameter
+ * also indicates if the field is synthetic and/or deprecated.
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the field's signature.
+ * @param value the field's initial value. This parameter, which may be {@literal null} if the
+ * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
+ * Long}, a {@link Double} or a {@link String}.
+ */
+ public FieldNode(
+ final int api,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ super(api);
+ this.access = access;
+ this.name = name;
+ this.desc = descriptor;
+ this.signature = signature;
+ this.value = value;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the FieldVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ if (visible) {
+ visibleAnnotations = Util.add(visibleAnnotations, annotation);
+ } else {
+ invisibleAnnotations = Util.add(invisibleAnnotations, annotation);
+ }
+ return annotation;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ visibleTypeAnnotations = Util.add(visibleTypeAnnotations, typeAnnotation);
+ } else {
+ invisibleTypeAnnotations = Util.add(invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ attrs = Util.add(attrs, attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accept methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Checks that this field node is compatible with the given ASM API version. This method checks
+ * that this node, and all its children recursively, do not contain elements that were introduced
+ * in more recent versions of the ASM API than the given version.
+ *
+ * @param api an ASM API version. Must be one of the {@code ASM}<i>x</i> values in {@link
+ * Opcodes}.
+ */
+ public void check(final int api) {
+ if (api == Opcodes.ASM4) {
+ if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ }
+
+ /**
+ * Makes the given class visitor visit this field.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ FieldVisitor fieldVisitor = classVisitor.visitField(access, name, desc, signature, value);
+ if (fieldVisitor == null) {
+ return;
+ }
+ // Visit the annotations.
+ if (visibleAnnotations != null) {
+ for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = visibleAnnotations.get(i);
+ annotation.accept(fieldVisitor.visitAnnotation(annotation.desc, true));
+ }
+ }
+ if (invisibleAnnotations != null) {
+ for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = invisibleAnnotations.get(i);
+ annotation.accept(fieldVisitor.visitAnnotation(annotation.desc, false));
+ }
+ }
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ fieldVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ fieldVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ // Visit the non standard attributes.
+ if (attrs != null) {
+ for (int i = 0, n = attrs.size(); i < n; ++i) {
+ fieldVisitor.visitAttribute(attrs.get(i));
+ }
+ }
+ fieldVisitor.visitEnd();
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/FrameNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/FrameNode.java
new file mode 100644
index 00000000..b7def5d1
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/FrameNode.java
@@ -0,0 +1,192 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a stack map frame. These nodes are pseudo instruction nodes in order to be
+ * inserted in an instruction list. In fact these nodes must(*) be inserted <i>just before</i> any
+ * instruction node <b>i</b> that follows an unconditionnal branch instruction such as GOTO or
+ * THROW, that is the target of a jump instruction, or that starts an exception handler block. The
+ * stack map frame types must describe the values of the local variables and of the operand stack
+ * elements <i>just before</i> <b>i</b> is executed. <br>
+ * <br>
+ * (*) this is mandatory only for classes whose version is greater than or equal to {@link
+ * Opcodes#V1_6}.
+ *
+ * @author Eric Bruneton
+ */
+public class FrameNode extends AbstractInsnNode {
+
+ /**
+ * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or {@link
+ * Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+ * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
+ */
+ public int type;
+
+ /**
+ * The types of the local variables of this stack map frame. Elements of this list can be Integer,
+ * String or LabelNode objects (for primitive, reference and uninitialized types respectively -
+ * see {@link MethodVisitor}).
+ */
+ public List<Object> local;
+
+ /**
+ * The types of the operand stack elements of this stack map frame. Elements of this list can be
+ * Integer, String or LabelNode objects (for primitive, reference and uninitialized types
+ * respectively - see {@link MethodVisitor}).
+ */
+ public List<Object> stack;
+
+ private FrameNode() {
+ super(-1);
+ }
+
+ /**
+ * Constructs a new {@link FrameNode}.
+ *
+ * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or
+ * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link
+ * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
+ * @param numLocal number of local variables of this stack map frame. Long and double values count
+ * for one variable.
+ * @param local the types of the local variables of this stack map frame. Elements of this list
+ * can be Integer, String or LabelNode objects (for primitive, reference and uninitialized
+ * types respectively - see {@link MethodVisitor}). Long and double values are represented by
+ * a single element.
+ * @param numStack number of operand stack elements of this stack map frame. Long and double
+ * values count for one stack element.
+ * @param stack the types of the operand stack elements of this stack map frame. Elements of this
+ * list can be Integer, String or LabelNode objects (for primitive, reference and
+ * uninitialized types respectively - see {@link MethodVisitor}). Long and double values are
+ * represented by a single element.
+ */
+ public FrameNode(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ super(-1);
+ this.type = type;
+ switch (type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ this.local = Util.asArrayList(numLocal, local);
+ this.stack = Util.asArrayList(numStack, stack);
+ break;
+ case Opcodes.F_APPEND:
+ this.local = Util.asArrayList(numLocal, local);
+ break;
+ case Opcodes.F_CHOP:
+ this.local = Util.asArrayList(numLocal);
+ break;
+ case Opcodes.F_SAME:
+ break;
+ case Opcodes.F_SAME1:
+ this.stack = Util.asArrayList(1, stack);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public int getType() {
+ return FRAME;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ switch (type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ methodVisitor.visitFrame(type, local.size(), asArray(local), stack.size(), asArray(stack));
+ break;
+ case Opcodes.F_APPEND:
+ methodVisitor.visitFrame(type, local.size(), asArray(local), 0, null);
+ break;
+ case Opcodes.F_CHOP:
+ methodVisitor.visitFrame(type, local.size(), null, 0, null);
+ break;
+ case Opcodes.F_SAME:
+ methodVisitor.visitFrame(type, 0, null, 0, null);
+ break;
+ case Opcodes.F_SAME1:
+ methodVisitor.visitFrame(type, 0, null, 1, asArray(stack));
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ FrameNode clone = new FrameNode();
+ clone.type = type;
+ if (local != null) {
+ clone.local = new ArrayList<>();
+ for (int i = 0, n = local.size(); i < n; ++i) {
+ Object localElement = local.get(i);
+ if (localElement instanceof LabelNode) {
+ localElement = clonedLabels.get(localElement);
+ }
+ clone.local.add(localElement);
+ }
+ }
+ if (stack != null) {
+ clone.stack = new ArrayList<>();
+ for (int i = 0, n = stack.size(); i < n; ++i) {
+ Object stackElement = stack.get(i);
+ if (stackElement instanceof LabelNode) {
+ stackElement = clonedLabels.get(stackElement);
+ }
+ clone.stack.add(stackElement);
+ }
+ }
+ return clone;
+ }
+
+ private static Object[] asArray(final List<Object> list) {
+ Object[] array = new Object[list.size()];
+ for (int i = 0, n = array.length; i < n; ++i) {
+ Object o = list.get(i);
+ if (o instanceof LabelNode) {
+ o = ((LabelNode) o).getLabel();
+ }
+ array[i] = o;
+ }
+ return array;
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/IincInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/IincInsnNode.java
new file mode 100644
index 00000000..b4aa027d
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/IincInsnNode.java
@@ -0,0 +1,74 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents an IINC instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class IincInsnNode extends AbstractInsnNode {
+
+ /** Index of the local variable to be incremented. */
+ public int var;
+
+ /** Amount to increment the local variable by. */
+ public int incr;
+
+ /**
+ * Constructs a new {@link IincInsnNode}.
+ *
+ * @param varIndex index of the local variable to be incremented.
+ * @param incr increment amount to increment the local variable by.
+ */
+ public IincInsnNode(final int varIndex, final int incr) {
+ super(Opcodes.IINC);
+ this.var = varIndex;
+ this.incr = incr;
+ }
+
+ @Override
+ public int getType() {
+ return IINC_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitIincInsn(var, incr);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new IincInsnNode(var, incr).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/InnerClassNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/InnerClassNode.java
new file mode 100644
index 00000000..ca9101b6
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/InnerClassNode.java
@@ -0,0 +1,91 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * A node that represents an inner class. This inner class is not necessarily a member of the {@link
+ * ClassNode} containing this object. More precisely, every class or interface C which is referenced
+ * by a {@link ClassNode} and which is not a package member must be represented with an {@link
+ * InnerClassNode}. The {@link ClassNode} must reference its nested class or interface members, and
+ * its enclosing class, if any. See the JVMS 4.7.6 section for more details.
+ *
+ * @author Eric Bruneton
+ */
+public class InnerClassNode {
+
+ /** The internal name of an inner class (see {@link org.objectweb.asm.Type#getInternalName()}). */
+ public String name;
+
+ /**
+ * The internal name of the class to which the inner class belongs (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public String outerName;
+
+ /**
+ * The (simple) name of the inner class inside its enclosing class. Must be {@literal null} if the
+ * inner class is not the member of a class or interface (e.g. for local or anonymous classes).
+ */
+ public String innerName;
+
+ /**
+ * The access flags of the inner class as originally declared in the source code from which the
+ * class was compiled.
+ */
+ public int access;
+
+ /**
+ * Constructs a new {@link InnerClassNode} for an inner class C.
+ *
+ * @param name the internal name of C (see {@link org.objectweb.asm.Type#getInternalName()}).
+ * @param outerName the internal name of the class or interface C is a member of (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). Must be {@literal null} if C is not the member
+ * of a class or interface (e.g. for local or anonymous classes).
+ * @param innerName the (simple) name of C. Must be {@literal null} for anonymous inner classes.
+ * @param access the access flags of C originally declared in the source code from which this
+ * class was compiled.
+ */
+ public InnerClassNode(
+ final String name, final String outerName, final String innerName, final int access) {
+ this.name = name;
+ this.outerName = outerName;
+ this.innerName = innerName;
+ this.access = access;
+ }
+
+ /**
+ * Makes the given class visitor visit this inner class.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ classVisitor.visitInnerClass(name, outerName, innerName, access);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java
new file mode 100644
index 00000000..1b6c5a05
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnList.java
@@ -0,0 +1,604 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A doubly linked list of {@link AbstractInsnNode} objects. <i>This implementation is not thread
+ * safe</i>.
+ */
+public class InsnList implements Iterable<AbstractInsnNode> {
+
+ /** The number of instructions in this list. */
+ private int size;
+
+ /** The first instruction in this list. May be {@literal null}. */
+ private AbstractInsnNode firstInsn;
+
+ /** The last instruction in this list. May be {@literal null}. */
+ private AbstractInsnNode lastInsn;
+
+ /**
+ * A cache of the instructions of this list. This cache is used to improve the performance of the
+ * {@link #get} method.
+ */
+ AbstractInsnNode[] cache;
+
+ /**
+ * Returns the number of instructions in this list.
+ *
+ * @return the number of instructions in this list.
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns the first instruction in this list.
+ *
+ * @return the first instruction in this list, or {@literal null} if the list is empty.
+ */
+ public AbstractInsnNode getFirst() {
+ return firstInsn;
+ }
+
+ /**
+ * Returns the last instruction in this list.
+ *
+ * @return the last instruction in this list, or {@literal null} if the list is empty.
+ */
+ public AbstractInsnNode getLast() {
+ return lastInsn;
+ }
+
+ /**
+ * Returns the instruction whose index is given. This method builds a cache of the instructions in
+ * this list to avoid scanning the whole list each time it is called. Once the cache is built,
+ * this method runs in constant time. This cache is invalidated by all the methods that modify the
+ * list.
+ *
+ * @param index the index of the instruction that must be returned.
+ * @return the instruction whose index is given.
+ * @throws IndexOutOfBoundsException if (index &lt; 0 || index &gt;= size()).
+ */
+ public AbstractInsnNode get(final int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (cache == null) {
+ cache = toArray();
+ }
+ return cache[index];
+ }
+
+ /**
+ * Returns {@literal true} if the given instruction belongs to this list. This method always scans
+ * the instructions of this list until it finds the given instruction or reaches the end of the
+ * list.
+ *
+ * @param insnNode an instruction.
+ * @return {@literal true} if the given instruction belongs to this list.
+ */
+ public boolean contains(final AbstractInsnNode insnNode) {
+ AbstractInsnNode currentInsn = firstInsn;
+ while (currentInsn != null && currentInsn != insnNode) {
+ currentInsn = currentInsn.nextInsn;
+ }
+ return currentInsn != null;
+ }
+
+ /**
+ * Returns the index of the given instruction in this list. This method builds a cache of the
+ * instruction indexes to avoid scanning the whole list each time it is called. Once the cache is
+ * built, this method run in constant time. The cache is invalidated by all the methods that
+ * modify the list.
+ *
+ * @param insnNode an instruction <i>of this list</i>.
+ * @return the index of the given instruction in this list. <i>The result of this method is
+ * undefined if the given instruction does not belong to this list</i>. Use {@link #contains }
+ * to test if an instruction belongs to an instruction list or not.
+ */
+ public int indexOf(final AbstractInsnNode insnNode) {
+ if (cache == null) {
+ cache = toArray();
+ }
+ return insnNode.index;
+ }
+
+ /**
+ * Makes the given visitor visit all the instructions in this list.
+ *
+ * @param methodVisitor the method visitor that must visit the instructions.
+ */
+ public void accept(final MethodVisitor methodVisitor) {
+ AbstractInsnNode currentInsn = firstInsn;
+ while (currentInsn != null) {
+ currentInsn.accept(methodVisitor);
+ currentInsn = currentInsn.nextInsn;
+ }
+ }
+
+ /**
+ * Returns an iterator over the instructions in this list.
+ *
+ * @return an iterator over the instructions in this list.
+ */
+ @Override
+ public ListIterator<AbstractInsnNode> iterator() {
+ return iterator(0);
+ }
+
+ /**
+ * Returns an iterator over the instructions in this list.
+ *
+ * @param index index of instruction for the iterator to start at.
+ * @return an iterator over the instructions in this list.
+ */
+ @SuppressWarnings("unchecked")
+ public ListIterator<AbstractInsnNode> iterator(final int index) {
+ return new InsnListIterator(index);
+ }
+
+ /**
+ * Returns an array containing all the instructions in this list.
+ *
+ * @return an array containing all the instructions in this list.
+ */
+ public AbstractInsnNode[] toArray() {
+ int currentInsnIndex = 0;
+ AbstractInsnNode currentInsn = firstInsn;
+ AbstractInsnNode[] insnNodeArray = new AbstractInsnNode[size];
+ while (currentInsn != null) {
+ insnNodeArray[currentInsnIndex] = currentInsn;
+ currentInsn.index = currentInsnIndex++;
+ currentInsn = currentInsn.nextInsn;
+ }
+ return insnNodeArray;
+ }
+
+ /**
+ * Replaces an instruction of this list with another instruction.
+ *
+ * @param oldInsnNode an instruction <i>of this list</i>.
+ * @param newInsnNode another instruction, <i>which must not belong to any {@link InsnList}</i>.
+ */
+ public void set(final AbstractInsnNode oldInsnNode, final AbstractInsnNode newInsnNode) {
+ AbstractInsnNode nextInsn = oldInsnNode.nextInsn;
+ newInsnNode.nextInsn = nextInsn;
+ if (nextInsn != null) {
+ nextInsn.previousInsn = newInsnNode;
+ } else {
+ lastInsn = newInsnNode;
+ }
+ AbstractInsnNode previousInsn = oldInsnNode.previousInsn;
+ newInsnNode.previousInsn = previousInsn;
+ if (previousInsn != null) {
+ previousInsn.nextInsn = newInsnNode;
+ } else {
+ firstInsn = newInsnNode;
+ }
+ if (cache != null) {
+ int index = oldInsnNode.index;
+ cache[index] = newInsnNode;
+ newInsnNode.index = index;
+ } else {
+ newInsnNode.index = 0; // newInsnNode now belongs to an InsnList.
+ }
+ oldInsnNode.index = -1; // oldInsnNode no longer belongs to an InsnList.
+ oldInsnNode.previousInsn = null;
+ oldInsnNode.nextInsn = null;
+ }
+
+ /**
+ * Adds the given instruction to the end of this list.
+ *
+ * @param insnNode an instruction, <i>which must not belong to any {@link InsnList}</i>.
+ */
+ public void add(final AbstractInsnNode insnNode) {
+ ++size;
+ if (lastInsn == null) {
+ firstInsn = insnNode;
+ lastInsn = insnNode;
+ } else {
+ lastInsn.nextInsn = insnNode;
+ insnNode.previousInsn = lastInsn;
+ }
+ lastInsn = insnNode;
+ cache = null;
+ insnNode.index = 0; // insnNode now belongs to an InsnList.
+ }
+
+ /**
+ * Adds the given instructions to the end of this list.
+ *
+ * @param insnList an instruction list, which is cleared during the process. This list must be
+ * different from 'this'.
+ */
+ public void add(final InsnList insnList) {
+ if (insnList.size == 0) {
+ return;
+ }
+ size += insnList.size;
+ if (lastInsn == null) {
+ firstInsn = insnList.firstInsn;
+ lastInsn = insnList.lastInsn;
+ } else {
+ AbstractInsnNode firstInsnListElement = insnList.firstInsn;
+ lastInsn.nextInsn = firstInsnListElement;
+ firstInsnListElement.previousInsn = lastInsn;
+ lastInsn = insnList.lastInsn;
+ }
+ cache = null;
+ insnList.removeAll(false);
+ }
+
+ /**
+ * Inserts the given instruction at the beginning of this list.
+ *
+ * @param insnNode an instruction, <i>which must not belong to any {@link InsnList}</i>.
+ */
+ public void insert(final AbstractInsnNode insnNode) {
+ ++size;
+ if (firstInsn == null) {
+ firstInsn = insnNode;
+ lastInsn = insnNode;
+ } else {
+ firstInsn.previousInsn = insnNode;
+ insnNode.nextInsn = firstInsn;
+ }
+ firstInsn = insnNode;
+ cache = null;
+ insnNode.index = 0; // insnNode now belongs to an InsnList.
+ }
+
+ /**
+ * Inserts the given instructions at the beginning of this list.
+ *
+ * @param insnList an instruction list, which is cleared during the process. This list must be
+ * different from 'this'.
+ */
+ public void insert(final InsnList insnList) {
+ if (insnList.size == 0) {
+ return;
+ }
+ size += insnList.size;
+ if (firstInsn == null) {
+ firstInsn = insnList.firstInsn;
+ lastInsn = insnList.lastInsn;
+ } else {
+ AbstractInsnNode lastInsnListElement = insnList.lastInsn;
+ firstInsn.previousInsn = lastInsnListElement;
+ lastInsnListElement.nextInsn = firstInsn;
+ firstInsn = insnList.firstInsn;
+ }
+ cache = null;
+ insnList.removeAll(false);
+ }
+
+ /**
+ * Inserts the given instruction after the specified instruction.
+ *
+ * @param previousInsn an instruction <i>of this list</i> after which insnNode must be inserted.
+ * @param insnNode the instruction to be inserted, <i>which must not belong to any {@link
+ * InsnList}</i>.
+ */
+ public void insert(final AbstractInsnNode previousInsn, final AbstractInsnNode insnNode) {
+ ++size;
+ AbstractInsnNode nextInsn = previousInsn.nextInsn;
+ if (nextInsn == null) {
+ lastInsn = insnNode;
+ } else {
+ nextInsn.previousInsn = insnNode;
+ }
+ previousInsn.nextInsn = insnNode;
+ insnNode.nextInsn = nextInsn;
+ insnNode.previousInsn = previousInsn;
+ cache = null;
+ insnNode.index = 0; // insnNode now belongs to an InsnList.
+ }
+
+ /**
+ * Inserts the given instructions after the specified instruction.
+ *
+ * @param previousInsn an instruction <i>of this list</i> after which the instructions must be
+ * inserted.
+ * @param insnList the instruction list to be inserted, which is cleared during the process. This
+ * list must be different from 'this'.
+ */
+ public void insert(final AbstractInsnNode previousInsn, final InsnList insnList) {
+ if (insnList.size == 0) {
+ return;
+ }
+ size += insnList.size;
+ AbstractInsnNode firstInsnListElement = insnList.firstInsn;
+ AbstractInsnNode lastInsnListElement = insnList.lastInsn;
+ AbstractInsnNode nextInsn = previousInsn.nextInsn;
+ if (nextInsn == null) {
+ lastInsn = lastInsnListElement;
+ } else {
+ nextInsn.previousInsn = lastInsnListElement;
+ }
+ previousInsn.nextInsn = firstInsnListElement;
+ lastInsnListElement.nextInsn = nextInsn;
+ firstInsnListElement.previousInsn = previousInsn;
+ cache = null;
+ insnList.removeAll(false);
+ }
+
+ /**
+ * Inserts the given instruction before the specified instruction.
+ *
+ * @param nextInsn an instruction <i>of this list</i> before which insnNode must be inserted.
+ * @param insnNode the instruction to be inserted, <i>which must not belong to any {@link
+ * InsnList}</i>.
+ */
+ public void insertBefore(final AbstractInsnNode nextInsn, final AbstractInsnNode insnNode) {
+ ++size;
+ AbstractInsnNode previousInsn = nextInsn.previousInsn;
+ if (previousInsn == null) {
+ firstInsn = insnNode;
+ } else {
+ previousInsn.nextInsn = insnNode;
+ }
+ nextInsn.previousInsn = insnNode;
+ insnNode.nextInsn = nextInsn;
+ insnNode.previousInsn = previousInsn;
+ cache = null;
+ insnNode.index = 0; // insnNode now belongs to an InsnList.
+ }
+
+ /**
+ * Inserts the given instructions before the specified instruction.
+ *
+ * @param nextInsn an instruction <i>of this list</i> before which the instructions must be
+ * inserted.
+ * @param insnList the instruction list to be inserted, which is cleared during the process. This
+ * list must be different from 'this'.
+ */
+ public void insertBefore(final AbstractInsnNode nextInsn, final InsnList insnList) {
+ if (insnList.size == 0) {
+ return;
+ }
+ size += insnList.size;
+ AbstractInsnNode firstInsnListElement = insnList.firstInsn;
+ AbstractInsnNode lastInsnListElement = insnList.lastInsn;
+ AbstractInsnNode previousInsn = nextInsn.previousInsn;
+ if (previousInsn == null) {
+ firstInsn = firstInsnListElement;
+ } else {
+ previousInsn.nextInsn = firstInsnListElement;
+ }
+ nextInsn.previousInsn = lastInsnListElement;
+ lastInsnListElement.nextInsn = nextInsn;
+ firstInsnListElement.previousInsn = previousInsn;
+ cache = null;
+ insnList.removeAll(false);
+ }
+
+ /**
+ * Removes the given instruction from this list.
+ *
+ * @param insnNode the instruction <i>of this list</i> that must be removed.
+ */
+ public void remove(final AbstractInsnNode insnNode) {
+ --size;
+ AbstractInsnNode nextInsn = insnNode.nextInsn;
+ AbstractInsnNode previousInsn = insnNode.previousInsn;
+ if (nextInsn == null) {
+ if (previousInsn == null) {
+ firstInsn = null;
+ lastInsn = null;
+ } else {
+ previousInsn.nextInsn = null;
+ lastInsn = previousInsn;
+ }
+ } else {
+ if (previousInsn == null) {
+ firstInsn = nextInsn;
+ nextInsn.previousInsn = null;
+ } else {
+ previousInsn.nextInsn = nextInsn;
+ nextInsn.previousInsn = previousInsn;
+ }
+ }
+ cache = null;
+ insnNode.index = -1; // insnNode no longer belongs to an InsnList.
+ insnNode.previousInsn = null;
+ insnNode.nextInsn = null;
+ }
+
+ /**
+ * Removes all the instructions of this list.
+ *
+ * @param mark if the instructions must be marked as no longer belonging to any {@link InsnList}.
+ */
+ void removeAll(final boolean mark) {
+ if (mark) {
+ AbstractInsnNode currentInsn = firstInsn;
+ while (currentInsn != null) {
+ AbstractInsnNode next = currentInsn.nextInsn;
+ currentInsn.index = -1; // currentInsn no longer belongs to an InsnList.
+ currentInsn.previousInsn = null;
+ currentInsn.nextInsn = null;
+ currentInsn = next;
+ }
+ }
+ size = 0;
+ firstInsn = null;
+ lastInsn = null;
+ cache = null;
+ }
+
+ /** Removes all the instructions of this list. */
+ public void clear() {
+ removeAll(false);
+ }
+
+ /**
+ * Resets all the labels in the instruction list. This method should be called before reusing an
+ * instruction list between several <code>ClassWriter</code>s.
+ */
+ public void resetLabels() {
+ AbstractInsnNode currentInsn = firstInsn;
+ while (currentInsn != null) {
+ if (currentInsn instanceof LabelNode) {
+ ((LabelNode) currentInsn).resetLabel();
+ }
+ currentInsn = currentInsn.nextInsn;
+ }
+ }
+
+ // Note: this class is not generified because it would create bridges.
+ @SuppressWarnings("rawtypes")
+ private final class InsnListIterator implements ListIterator {
+
+ AbstractInsnNode nextInsn;
+
+ AbstractInsnNode previousInsn;
+
+ AbstractInsnNode remove;
+
+ InsnListIterator(final int index) {
+ if (index < 0 || index > size()) {
+ throw new IndexOutOfBoundsException();
+ } else if (index == size()) {
+ nextInsn = null;
+ previousInsn = getLast();
+ } else {
+ AbstractInsnNode currentInsn = getFirst();
+ for (int i = 0; i < index; i++) {
+ currentInsn = currentInsn.nextInsn;
+ }
+
+ nextInsn = currentInsn;
+ previousInsn = currentInsn.previousInsn;
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return nextInsn != null;
+ }
+
+ @Override
+ public Object next() {
+ if (nextInsn == null) {
+ throw new NoSuchElementException();
+ }
+ AbstractInsnNode result = nextInsn;
+ previousInsn = result;
+ nextInsn = result.nextInsn;
+ remove = result;
+ return result;
+ }
+
+ @Override
+ public void remove() {
+ if (remove != null) {
+ if (remove == nextInsn) {
+ nextInsn = nextInsn.nextInsn;
+ } else {
+ previousInsn = previousInsn.previousInsn;
+ }
+ InsnList.this.remove(remove);
+ remove = null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return previousInsn != null;
+ }
+
+ @Override
+ public Object previous() {
+ if (previousInsn == null) {
+ throw new NoSuchElementException();
+ }
+ AbstractInsnNode result = previousInsn;
+ nextInsn = result;
+ previousInsn = result.previousInsn;
+ remove = result;
+ return result;
+ }
+
+ @Override
+ public int nextIndex() {
+ if (nextInsn == null) {
+ return size();
+ }
+ if (cache == null) {
+ cache = toArray();
+ }
+ return nextInsn.index;
+ }
+
+ @Override
+ public int previousIndex() {
+ if (previousInsn == null) {
+ return -1;
+ }
+ if (cache == null) {
+ cache = toArray();
+ }
+ return previousInsn.index;
+ }
+
+ @Override
+ public void add(final Object o) {
+ if (nextInsn != null) {
+ InsnList.this.insertBefore(nextInsn, (AbstractInsnNode) o);
+ } else if (previousInsn != null) {
+ InsnList.this.insert(previousInsn, (AbstractInsnNode) o);
+ } else {
+ InsnList.this.add((AbstractInsnNode) o);
+ }
+ previousInsn = (AbstractInsnNode) o;
+ remove = null;
+ }
+
+ @Override
+ public void set(final Object o) {
+ if (remove != null) {
+ InsnList.this.set(remove, (AbstractInsnNode) o);
+ if (remove == previousInsn) {
+ previousInsn = (AbstractInsnNode) o;
+ } else {
+ nextInsn = (AbstractInsnNode) o;
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/InsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnNode.java
new file mode 100644
index 00000000..5b272321
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/InsnNode.java
@@ -0,0 +1,73 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a zero operand instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class InsnNode extends AbstractInsnNode {
+
+ /**
+ * Constructs a new {@link InsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed. This opcode must be NOP,
+ * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
+ * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
+ * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
+ * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
+ * SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
+ * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
+ * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
+ * D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
+ */
+ public InsnNode(final int opcode) {
+ super(opcode);
+ }
+
+ @Override
+ public int getType() {
+ return INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitInsn(opcode);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new InsnNode(opcode).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/IntInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/IntInsnNode.java
new file mode 100644
index 00000000..baea8d3f
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/IntInsnNode.java
@@ -0,0 +1,79 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents an instruction with a single int operand.
+ *
+ * @author Eric Bruneton
+ */
+public class IntInsnNode extends AbstractInsnNode {
+
+ /** The operand of this instruction. */
+ public int operand;
+
+ /**
+ * Constructs a new {@link IntInsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed. This opcode must be BIPUSH,
+ * SIPUSH or NEWARRAY.
+ * @param operand the operand of the instruction to be constructed.
+ */
+ public IntInsnNode(final int opcode, final int operand) {
+ super(opcode);
+ this.operand = operand;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be BIPUSH, SIPUSH or NEWARRAY.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return INT_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitIntInsn(opcode, operand);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new IntInsnNode(opcode, operand).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/InvokeDynamicInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/InvokeDynamicInsnNode.java
new file mode 100644
index 00000000..8bb87124
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/InvokeDynamicInsnNode.java
@@ -0,0 +1,92 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents an invokedynamic instruction.
+ *
+ * @author Remi Forax
+ */
+public class InvokeDynamicInsnNode extends AbstractInsnNode {
+
+ /** The method's name. */
+ public String name;
+
+ /** The method's descriptor (see {@link org.objectweb.asm.Type}). */
+ public String desc;
+
+ /** The bootstrap method. */
+ public Handle bsm;
+
+ /** The bootstrap method constant arguments. */
+ public Object[] bsmArgs;
+
+ /**
+ * Constructs a new {@link InvokeDynamicInsnNode}.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
+ * org.objectweb.asm.Type} or {@link Handle} value. This method is allowed to modify the
+ * content of the array so a caller should expect that this array may change.
+ */
+ public InvokeDynamicInsnNode(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) { // NOPMD(ArrayIsStoredDirectly): public field.
+ super(Opcodes.INVOKEDYNAMIC);
+ this.name = name;
+ this.desc = descriptor;
+ this.bsm = bootstrapMethodHandle;
+ this.bsmArgs = bootstrapMethodArguments;
+ }
+
+ @Override
+ public int getType() {
+ return INVOKE_DYNAMIC_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/JumpInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/JumpInsnNode.java
new file mode 100644
index 00000000..793c0713
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/JumpInsnNode.java
@@ -0,0 +1,87 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a jump instruction. A jump instruction is an instruction that may jump to
+ * another instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class JumpInsnNode extends AbstractInsnNode {
+
+ /**
+ * The operand of this instruction. This operand is a label that designates the instruction to
+ * which this instruction may jump.
+ */
+ public LabelNode label;
+
+ /**
+ * Constructs a new {@link JumpInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This opcode must be IFEQ,
+ * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
+ * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label the operand of the instruction to be constructed. This operand is a label that
+ * designates the instruction to which the jump instruction may jump.
+ */
+ public JumpInsnNode(final int opcode, final LabelNode label) {
+ super(opcode);
+ this.label = label;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT,
+ * IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
+ * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return JUMP_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitJumpInsn(opcode, label.getLabel());
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new JumpInsnNode(opcode, clone(label, clonedLabels)).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LabelNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LabelNode.java
new file mode 100644
index 00000000..dd11f46c
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LabelNode.java
@@ -0,0 +1,79 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/** An {@link AbstractInsnNode} that encapsulates a {@link Label}. */
+public class LabelNode extends AbstractInsnNode {
+
+ private Label value;
+
+ public LabelNode() {
+ super(-1);
+ }
+
+ public LabelNode(final Label label) {
+ super(-1);
+ this.value = label;
+ }
+
+ @Override
+ public int getType() {
+ return LABEL;
+ }
+
+ /**
+ * Returns the label encapsulated by this node. A new label is created and associated with this
+ * node if it was created without an encapsulated label.
+ *
+ * @return the label encapsulated by this node.
+ */
+ public Label getLabel() {
+ if (value == null) {
+ value = new Label();
+ }
+ return value;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitLabel(getLabel());
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return clonedLabels.get(this);
+ }
+
+ public void resetLabel() {
+ value = null;
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LdcInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LdcInsnNode.java
new file mode 100644
index 00000000..8697e2b0
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LdcInsnNode.java
@@ -0,0 +1,83 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A node that represents an LDC instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class LdcInsnNode extends AbstractInsnNode {
+
+ /**
+ * The constant to be loaded on the stack. This field must be a non null {@link Integer}, a {@link
+ * Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY
+ * sort for {@code .class} constants, for classes whose version is 49, a {@link Type} of METHOD
+ * sort for MethodType, a {@link Handle} for MethodHandle constants, for classes whose version is
+ * 51 or a {@link ConstantDynamic} for a constant dynamic for classes whose version is 55.
+ */
+ public Object cst;
+
+ /**
+ * Constructs a new {@link LdcInsnNode}.
+ *
+ * @param value the constant to be loaded on the stack. This parameter mist be a non null {@link
+ * Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
+ * Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
+ * 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
+ * constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
+ * dynamic for classes whose version is 55.
+ */
+ public LdcInsnNode(final Object value) {
+ super(Opcodes.LDC);
+ this.cst = value;
+ }
+
+ @Override
+ public int getType() {
+ return LDC_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitLdcInsn(cst);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new LdcInsnNode(cst).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LineNumberNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LineNumberNode.java
new file mode 100644
index 00000000..cde8fada
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LineNumberNode.java
@@ -0,0 +1,74 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a line number declaration. These nodes are pseudo instruction nodes in
+ * order to be inserted in an instruction list.
+ *
+ * @author Eric Bruneton
+ */
+public class LineNumberNode extends AbstractInsnNode {
+
+ /** A line number. This number refers to the source file from which the class was compiled. */
+ public int line;
+
+ /** The first instruction corresponding to this line number. */
+ public LabelNode start;
+
+ /**
+ * Constructs a new {@link LineNumberNode}.
+ *
+ * @param line a line number. This number refers to the source file from which the class was
+ * compiled.
+ * @param start the first instruction corresponding to this line number.
+ */
+ public LineNumberNode(final int line, final LabelNode start) {
+ super(-1);
+ this.line = line;
+ this.start = start;
+ }
+
+ @Override
+ public int getType() {
+ return LINE;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitLineNumber(line, start.getLabel());
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new LineNumberNode(line, clone(start, clonedLabels));
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java
new file mode 100644
index 00000000..1bf10a9c
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java
@@ -0,0 +1,140 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a type annotation on a local or resource variable.
+ *
+ * @author Eric Bruneton
+ */
+public class LocalVariableAnnotationNode extends TypeAnnotationNode {
+
+ /**
+ * The fist instructions corresponding to the continuous ranges that make the scope of this local
+ * variable (inclusive). Must not be {@literal null}.
+ */
+ public List<LabelNode> start;
+
+ /**
+ * The last instructions corresponding to the continuous ranges that make the scope of this local
+ * variable (exclusive). This list must have the same size as the 'start' list. Must not be
+ * {@literal null}.
+ */
+ public List<LabelNode> end;
+
+ /**
+ * The local variable's index in each range. This list must have the same size as the 'start'
+ * list. Must not be {@literal null}.
+ */
+ public List<Integer> index;
+
+ /**
+ * Constructs a new {@link LocalVariableAnnotationNode}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link #LocalVariableAnnotationNode(int, TypePath,
+ * LabelNode[], LabelNode[], int[], String)} version.
+ *
+ * @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param start the fist instructions corresponding to the continuous ranges that make the scope
+ * of this local variable (inclusive).
+ * @param end the last instructions corresponding to the continuous ranges that make the scope of
+ * this local variable (exclusive). This array must have the same size as the 'start' array.
+ * @param index the local variable's index in each range. This array must have the same size as
+ * the 'start' array.
+ * @param descriptor the class descriptor of the annotation class.
+ */
+ public LocalVariableAnnotationNode(
+ final int typeRef,
+ final TypePath typePath,
+ final LabelNode[] start,
+ final LabelNode[] end,
+ final int[] index,
+ final String descriptor) {
+ this(/* latest api = */ Opcodes.ASM9, typeRef, typePath, start, end, index, descriptor);
+ }
+
+ /**
+ * Constructs a new {@link LocalVariableAnnotationNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
+ * @param start the fist instructions corresponding to the continuous ranges that make the scope
+ * of this local variable (inclusive).
+ * @param end the last instructions corresponding to the continuous ranges that make the scope of
+ * this local variable (exclusive). This array must have the same size as the 'start' array.
+ * @param index the local variable's index in each range. This array must have the same size as
+ * the 'start' array.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ */
+ public LocalVariableAnnotationNode(
+ final int api,
+ final int typeRef,
+ final TypePath typePath,
+ final LabelNode[] start,
+ final LabelNode[] end,
+ final int[] index,
+ final String descriptor) {
+ super(api, typeRef, typePath, descriptor);
+ this.start = Util.asArrayList(start);
+ this.end = Util.asArrayList(end);
+ this.index = Util.asArrayList(index);
+ }
+
+ /**
+ * Makes the given visitor visit this type annotation.
+ *
+ * @param methodVisitor the visitor that must visit this annotation.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ */
+ public void accept(final MethodVisitor methodVisitor, final boolean visible) {
+ Label[] startLabels = new Label[this.start.size()];
+ Label[] endLabels = new Label[this.end.size()];
+ int[] indices = new int[this.index.size()];
+ for (int i = 0, n = startLabels.length; i < n; ++i) {
+ startLabels[i] = this.start.get(i).getLabel();
+ endLabels[i] = this.end.get(i).getLabel();
+ indices[i] = this.index.get(i);
+ }
+ accept(
+ methodVisitor.visitLocalVariableAnnotation(
+ typeRef, typePath, startLabels, endLabels, indices, desc, visible));
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableNode.java
new file mode 100644
index 00000000..cabd0a20
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableNode.java
@@ -0,0 +1,92 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a local variable declaration.
+ *
+ * @author Eric Bruneton
+ */
+public class LocalVariableNode {
+
+ /** The name of a local variable. */
+ public String name;
+
+ /** The type descriptor of this local variable. */
+ public String desc;
+
+ /** The signature of this local variable. May be {@literal null}. */
+ public String signature;
+
+ /** The first instruction corresponding to the scope of this local variable (inclusive). */
+ public LabelNode start;
+
+ /** The last instruction corresponding to the scope of this local variable (exclusive). */
+ public LabelNode end;
+
+ /** The local variable's index. */
+ public int index;
+
+ /**
+ * Constructs a new {@link LocalVariableNode}.
+ *
+ * @param name the name of a local variable.
+ * @param descriptor the type descriptor of this local variable.
+ * @param signature the signature of this local variable. May be {@literal null}.
+ * @param start the first instruction corresponding to the scope of this local variable
+ * (inclusive).
+ * @param end the last instruction corresponding to the scope of this local variable (exclusive).
+ * @param index the local variable's index.
+ */
+ public LocalVariableNode(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final LabelNode start,
+ final LabelNode end,
+ final int index) {
+ this.name = name;
+ this.desc = descriptor;
+ this.signature = signature;
+ this.start = start;
+ this.end = end;
+ this.index = index;
+ }
+
+ /**
+ * Makes the given visitor visit this local variable declaration.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitLocalVariable(
+ name, desc, signature, start.getLabel(), end.getLabel(), index);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LookupSwitchInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LookupSwitchInsnNode.java
new file mode 100644
index 00000000..5e26f521
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LookupSwitchInsnNode.java
@@ -0,0 +1,93 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a LOOKUPSWITCH instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class LookupSwitchInsnNode extends AbstractInsnNode {
+
+ /** Beginning of the default handler block. */
+ public LabelNode dflt;
+
+ /** The values of the keys. */
+ public List<Integer> keys;
+
+ /** Beginnings of the handler blocks. */
+ public List<LabelNode> labels;
+
+ /**
+ * Constructs a new {@link LookupSwitchInsnNode}.
+ *
+ * @param dflt beginning of the default handler block.
+ * @param keys the values of the keys.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code keys[i]} key.
+ */
+ public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
+ super(Opcodes.LOOKUPSWITCH);
+ this.dflt = dflt;
+ this.keys = Util.asArrayList(keys);
+ this.labels = Util.asArrayList(labels);
+ }
+
+ @Override
+ public int getType() {
+ return LOOKUPSWITCH_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ int[] keysArray = new int[this.keys.size()];
+ for (int i = 0, n = keysArray.length; i < n; ++i) {
+ keysArray[i] = this.keys.get(i).intValue();
+ }
+ Label[] labelsArray = new Label[this.labels.size()];
+ for (int i = 0, n = labelsArray.length; i < n; ++i) {
+ labelsArray[i] = this.labels.get(i).getLabel();
+ }
+ methodVisitor.visitLookupSwitchInsn(dflt.getLabel(), keysArray, labelsArray);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ LookupSwitchInsnNode clone =
+ new LookupSwitchInsnNode(clone(dflt, clonedLabels), null, clone(labels, clonedLabels));
+ clone.keys.addAll(keys);
+ return clone.cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodInsnNode.java
new file mode 100644
index 00000000..eeb969f9
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodInsnNode.java
@@ -0,0 +1,123 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a method instruction. A method instruction is an instruction that invokes
+ * a method.
+ *
+ * @author Eric Bruneton
+ */
+public class MethodInsnNode extends AbstractInsnNode {
+
+ /**
+ * The internal name of the method's owner class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ *
+ * <p>For methods of arrays, e.g., {@code clone()}, the array type descriptor.
+ */
+ public String owner;
+
+ /** The method's name. */
+ public String name;
+
+ /** The method's descriptor (see {@link org.objectweb.asm.Type}). */
+ public String desc;
+
+ /** Whether the method's owner class if an interface. */
+ public boolean itf;
+
+ /**
+ * Constructs a new {@link MethodInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This opcode must be
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link org.objectweb.asm.Type}).
+ */
+ public MethodInsnNode(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ this(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
+ }
+
+ /**
+ * Constructs a new {@link MethodInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This opcode must be
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public MethodInsnNode(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ super(opcode);
+ this.owner = owner;
+ this.name = name;
+ this.desc = descriptor;
+ this.itf = isInterface;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be INVOKEVIRTUAL, INVOKESPECIAL,
+ * INVOKESTATIC or INVOKEINTERFACE.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return METHOD_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitMethodInsn(opcode, owner, name, desc, itf);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new MethodInsnNode(opcode, owner, name, desc, itf).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java
new file mode 100644
index 00000000..23e3e4c5
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java
@@ -0,0 +1,772 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a method.
+ *
+ * @author Eric Bruneton
+ */
+public class MethodNode extends MethodVisitor {
+
+ /**
+ * The method's access flags (see {@link Opcodes}). This field also indicates if the method is
+ * synthetic and/or deprecated.
+ */
+ public int access;
+
+ /** The method's name. */
+ public String name;
+
+ /** The method's descriptor (see {@link Type}). */
+ public String desc;
+
+ /** The method's signature. May be {@literal null}. */
+ public String signature;
+
+ /** The internal names of the method's exception classes (see {@link Type#getInternalName()}). */
+ public List<String> exceptions;
+
+ /** The method parameter info (access flags and name). */
+ public List<ParameterNode> parameters;
+
+ /** The runtime visible annotations of this method. May be {@literal null}. */
+ public List<AnnotationNode> visibleAnnotations;
+
+ /** The runtime invisible annotations of this method. May be {@literal null}. */
+ public List<AnnotationNode> invisibleAnnotations;
+
+ /** The runtime visible type annotations of this method. May be {@literal null}. */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /** The runtime invisible type annotations of this method. May be {@literal null}. */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /** The non standard attributes of this method. May be {@literal null}. */
+ public List<Attribute> attrs;
+
+ /**
+ * The default value of this annotation interface method. This field must be a {@link Byte},
+ * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link
+ * Float}, {@link Double}, {@link String} or {@link Type}, or an two elements String array (for
+ * enumeration values), a {@link AnnotationNode}, or a {@link List} of values of one of the
+ * preceding types. May be {@literal null}.
+ */
+ public Object annotationDefault;
+
+ /**
+ * The number of method parameters than can have runtime visible annotations. This number must be
+ * less or equal than the number of parameter types in the method descriptor (the default value 0
+ * indicates that all the parameters described in the method descriptor can have annotations). It
+ * can be strictly less when a method has synthetic parameters and when these parameters are
+ * ignored when computing parameter indices for the purpose of parameter annotations (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ */
+ public int visibleAnnotableParameterCount;
+
+ /**
+ * The runtime visible parameter annotations of this method. These lists are lists of {@link
+ * AnnotationNode} objects. May be {@literal null}.
+ */
+ public List<AnnotationNode>[] visibleParameterAnnotations;
+
+ /**
+ * The number of method parameters than can have runtime invisible annotations. This number must
+ * be less or equal than the number of parameter types in the method descriptor (the default value
+ * 0 indicates that all the parameters described in the method descriptor can have annotations).
+ * It can be strictly less when a method has synthetic parameters and when these parameters are
+ * ignored when computing parameter indices for the purpose of parameter annotations (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ */
+ public int invisibleAnnotableParameterCount;
+
+ /**
+ * The runtime invisible parameter annotations of this method. These lists are lists of {@link
+ * AnnotationNode} objects. May be {@literal null}.
+ */
+ public List<AnnotationNode>[] invisibleParameterAnnotations;
+
+ /** The instructions of this method. */
+ public InsnList instructions;
+
+ /** The try catch blocks of this method. */
+ public List<TryCatchBlockNode> tryCatchBlocks;
+
+ /** The maximum stack size of this method. */
+ public int maxStack;
+
+ /** The maximum number of local variables of this method. */
+ public int maxLocals;
+
+ /** The local variables of this method. May be {@literal null} */
+ public List<LocalVariableNode> localVariables;
+
+ /** The visible local variable annotations of this method. May be {@literal null} */
+ public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
+
+ /** The invisible local variable annotations of this method. May be {@literal null} */
+ public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
+
+ /** Whether the accept method has been called on this object. */
+ private boolean visited;
+
+ /**
+ * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link #MethodNode(int)} version.
+ *
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public MethodNode() {
+ this(/* latest api = */ Opcodes.ASM9);
+ if (getClass() != MethodNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs an uninitialized {@link MethodNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ public MethodNode(final int api) {
+ super(api);
+ this.instructions = new InsnList();
+ }
+
+ /**
+ * Constructs a new {@link MethodNode}. <i>Subclasses must not use this constructor</i>. Instead,
+ * they must use the {@link #MethodNode(int, int, String, String, String, String[])} version.
+ *
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public MethodNode(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ this(/* latest api = */ Opcodes.ASM9, access, name, descriptor, signature, exceptions);
+ if (getClass() != MethodNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link MethodNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ */
+ public MethodNode(
+ final int api,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ super(api);
+ this.access = access;
+ this.name = name;
+ this.desc = descriptor;
+ this.signature = signature;
+ this.exceptions = Util.asArrayList(exceptions);
+ if ((access & Opcodes.ACC_ABSTRACT) == 0) {
+ this.localVariables = new ArrayList<>(5);
+ }
+ this.tryCatchBlocks = new ArrayList<>();
+ this.instructions = new InsnList();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the MethodVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ if (parameters == null) {
+ parameters = new ArrayList<>(5);
+ }
+ parameters.add(new ParameterNode(name, access));
+ }
+
+ @Override
+ @SuppressWarnings("serial")
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new AnnotationNode(
+ new ArrayList<Object>(0) {
+ @Override
+ public boolean add(final Object o) {
+ annotationDefault = o;
+ return super.add(o);
+ }
+ });
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ if (visible) {
+ visibleAnnotations = Util.add(visibleAnnotations, annotation);
+ } else {
+ invisibleAnnotations = Util.add(invisibleAnnotations, annotation);
+ }
+ return annotation;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ visibleTypeAnnotations = Util.add(visibleTypeAnnotations, typeAnnotation);
+ } else {
+ invisibleTypeAnnotations = Util.add(invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ if (visible) {
+ visibleAnnotableParameterCount = parameterCount;
+ } else {
+ invisibleAnnotableParameterCount = parameterCount;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ if (visible) {
+ if (visibleParameterAnnotations == null) {
+ int params = Type.getArgumentTypes(desc).length;
+ visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
+ }
+ visibleParameterAnnotations[parameter] =
+ Util.add(visibleParameterAnnotations[parameter], annotation);
+ } else {
+ if (invisibleParameterAnnotations == null) {
+ int params = Type.getArgumentTypes(desc).length;
+ invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
+ }
+ invisibleParameterAnnotations[parameter] =
+ Util.add(invisibleParameterAnnotations[parameter], annotation);
+ }
+ return annotation;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ attrs = Util.add(attrs, attribute);
+ }
+
+ @Override
+ public void visitCode() {
+ // Nothing to do.
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ instructions.add(
+ new FrameNode(
+ type,
+ numLocal,
+ local == null ? null : getLabelNodes(local),
+ numStack,
+ stack == null ? null : getLabelNodes(stack)));
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ instructions.add(new InsnNode(opcode));
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ instructions.add(new IntInsnNode(opcode, operand));
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ instructions.add(new VarInsnNode(opcode, varIndex));
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ instructions.add(new TypeInsnNode(opcode, type));
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ instructions.add(new FieldInsnNode(opcode, owner, name, descriptor));
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ instructions.add(new MethodInsnNode(opcode, owner, name, descriptor, isInterface));
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ instructions.add(
+ new InvokeDynamicInsnNode(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments));
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ instructions.add(new JumpInsnNode(opcode, getLabelNode(label)));
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ instructions.add(getLabelNode(label));
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ instructions.add(new LdcInsnNode(value));
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ instructions.add(new IincInsnNode(varIndex, increment));
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels)));
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels)));
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ instructions.add(new MultiANewArrayInsnNode(descriptor, numDimensions));
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ // Find the last real instruction, i.e. the instruction targeted by this annotation.
+ AbstractInsnNode currentInsn = instructions.getLast();
+ while (currentInsn.getOpcode() == -1) {
+ currentInsn = currentInsn.getPrevious();
+ }
+ // Add the annotation to this instruction.
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ currentInsn.visibleTypeAnnotations =
+ Util.add(currentInsn.visibleTypeAnnotations, typeAnnotation);
+ } else {
+ currentInsn.invisibleTypeAnnotations =
+ Util.add(currentInsn.invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ TryCatchBlockNode tryCatchBlock =
+ new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), getLabelNode(handler), type);
+ tryCatchBlocks = Util.add(tryCatchBlocks, tryCatchBlock);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ tryCatchBlock.visibleTypeAnnotations =
+ Util.add(tryCatchBlock.visibleTypeAnnotations, typeAnnotation);
+ } else {
+ tryCatchBlock.invisibleTypeAnnotations =
+ Util.add(tryCatchBlock.invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ LocalVariableNode localVariable =
+ new LocalVariableNode(
+ name, descriptor, signature, getLabelNode(start), getLabelNode(end), index);
+ localVariables = Util.add(localVariables, localVariable);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ LocalVariableAnnotationNode localVariableAnnotation =
+ new LocalVariableAnnotationNode(
+ typeRef, typePath, getLabelNodes(start), getLabelNodes(end), index, descriptor);
+ if (visible) {
+ visibleLocalVariableAnnotations =
+ Util.add(visibleLocalVariableAnnotations, localVariableAnnotation);
+ } else {
+ invisibleLocalVariableAnnotations =
+ Util.add(invisibleLocalVariableAnnotations, localVariableAnnotation);
+ }
+ return localVariableAnnotation;
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ instructions.add(new LineNumberNode(line, getLabelNode(start)));
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ /**
+ * Returns the LabelNode corresponding to the given Label. Creates a new LabelNode if necessary.
+ * The default implementation of this method uses the {@link Label#info} field to store
+ * associations between labels and label nodes.
+ *
+ * @param label a Label.
+ * @return the LabelNode corresponding to label.
+ */
+ protected LabelNode getLabelNode(final Label label) {
+ if (!(label.info instanceof LabelNode)) {
+ label.info = new LabelNode();
+ }
+ return (LabelNode) label.info;
+ }
+
+ private LabelNode[] getLabelNodes(final Label[] labels) {
+ LabelNode[] labelNodes = new LabelNode[labels.length];
+ for (int i = 0, n = labels.length; i < n; ++i) {
+ labelNodes[i] = getLabelNode(labels[i]);
+ }
+ return labelNodes;
+ }
+
+ private Object[] getLabelNodes(final Object[] objects) {
+ Object[] labelNodes = new Object[objects.length];
+ for (int i = 0, n = objects.length; i < n; ++i) {
+ Object o = objects[i];
+ if (o instanceof Label) {
+ o = getLabelNode((Label) o);
+ }
+ labelNodes[i] = o;
+ }
+ return labelNodes;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accept method
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Checks that this method node is compatible with the given ASM API version. This method checks
+ * that this node, and all its children recursively, do not contain elements that were introduced
+ * in more recent versions of the ASM API than the given version.
+ *
+ * @param api an ASM API version. Must be one of the {@code ASM}<i>x</i> values in {@link
+ * Opcodes}.
+ */
+ public void check(final int api) {
+ if (api == Opcodes.ASM4) {
+ if (parameters != null && !parameters.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (tryCatchBlocks != null) {
+ for (int i = tryCatchBlocks.size() - 1; i >= 0; --i) {
+ TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get(i);
+ if (tryCatchBlock.visibleTypeAnnotations != null
+ && !tryCatchBlock.visibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (tryCatchBlock.invisibleTypeAnnotations != null
+ && !tryCatchBlock.invisibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ }
+ for (int i = instructions.size() - 1; i >= 0; --i) {
+ AbstractInsnNode insn = instructions.get(i);
+ if (insn.visibleTypeAnnotations != null && !insn.visibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (insn.invisibleTypeAnnotations != null && !insn.invisibleTypeAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (insn instanceof MethodInsnNode) {
+ boolean isInterface = ((MethodInsnNode) insn).itf;
+ if (isInterface != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
+ throw new UnsupportedClassVersionException();
+ }
+ } else if (insn instanceof LdcInsnNode) {
+ Object value = ((LdcInsnNode) insn).cst;
+ if (value instanceof Handle
+ || (value instanceof Type && ((Type) value).getSort() == Type.METHOD)) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ }
+ if (visibleLocalVariableAnnotations != null && !visibleLocalVariableAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ if (invisibleLocalVariableAnnotations != null
+ && !invisibleLocalVariableAnnotations.isEmpty()) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ if (api < Opcodes.ASM7) {
+ for (int i = instructions.size() - 1; i >= 0; --i) {
+ AbstractInsnNode insn = instructions.get(i);
+ if (insn instanceof LdcInsnNode) {
+ Object value = ((LdcInsnNode) insn).cst;
+ if (value instanceof ConstantDynamic) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Makes the given class visitor visit this method.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ String[] exceptionsArray = exceptions == null ? null : exceptions.toArray(new String[0]);
+ MethodVisitor methodVisitor =
+ classVisitor.visitMethod(access, name, desc, signature, exceptionsArray);
+ if (methodVisitor != null) {
+ accept(methodVisitor);
+ }
+ }
+
+ /**
+ * Makes the given method visitor visit this method.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ public void accept(final MethodVisitor methodVisitor) {
+ // Visit the parameters.
+ if (parameters != null) {
+ for (int i = 0, n = parameters.size(); i < n; i++) {
+ parameters.get(i).accept(methodVisitor);
+ }
+ }
+ // Visit the annotations.
+ if (annotationDefault != null) {
+ AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault();
+ AnnotationNode.accept(annotationVisitor, null, annotationDefault);
+ if (annotationVisitor != null) {
+ annotationVisitor.visitEnd();
+ }
+ }
+ if (visibleAnnotations != null) {
+ for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = visibleAnnotations.get(i);
+ annotation.accept(methodVisitor.visitAnnotation(annotation.desc, true));
+ }
+ }
+ if (invisibleAnnotations != null) {
+ for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = invisibleAnnotations.get(i);
+ annotation.accept(methodVisitor.visitAnnotation(annotation.desc, false));
+ }
+ }
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ if (visibleAnnotableParameterCount > 0) {
+ methodVisitor.visitAnnotableParameterCount(visibleAnnotableParameterCount, true);
+ }
+ if (visibleParameterAnnotations != null) {
+ for (int i = 0, n = visibleParameterAnnotations.length; i < n; ++i) {
+ List<AnnotationNode> parameterAnnotations = visibleParameterAnnotations[i];
+ if (parameterAnnotations == null) {
+ continue;
+ }
+ for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) {
+ AnnotationNode annotation = parameterAnnotations.get(j);
+ annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, true));
+ }
+ }
+ }
+ if (invisibleAnnotableParameterCount > 0) {
+ methodVisitor.visitAnnotableParameterCount(invisibleAnnotableParameterCount, false);
+ }
+ if (invisibleParameterAnnotations != null) {
+ for (int i = 0, n = invisibleParameterAnnotations.length; i < n; ++i) {
+ List<AnnotationNode> parameterAnnotations = invisibleParameterAnnotations[i];
+ if (parameterAnnotations == null) {
+ continue;
+ }
+ for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) {
+ AnnotationNode annotation = parameterAnnotations.get(j);
+ annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, false));
+ }
+ }
+ }
+ // Visit the non standard attributes.
+ if (visited) {
+ instructions.resetLabels();
+ }
+ if (attrs != null) {
+ for (int i = 0, n = attrs.size(); i < n; ++i) {
+ methodVisitor.visitAttribute(attrs.get(i));
+ }
+ }
+ // Visit the code.
+ if (instructions.size() > 0) {
+ methodVisitor.visitCode();
+ // Visits the try catch blocks.
+ if (tryCatchBlocks != null) {
+ for (int i = 0, n = tryCatchBlocks.size(); i < n; ++i) {
+ tryCatchBlocks.get(i).updateIndex(i);
+ tryCatchBlocks.get(i).accept(methodVisitor);
+ }
+ }
+ // Visit the instructions.
+ instructions.accept(methodVisitor);
+ // Visits the local variables.
+ if (localVariables != null) {
+ for (int i = 0, n = localVariables.size(); i < n; ++i) {
+ localVariables.get(i).accept(methodVisitor);
+ }
+ }
+ // Visits the local variable annotations.
+ if (visibleLocalVariableAnnotations != null) {
+ for (int i = 0, n = visibleLocalVariableAnnotations.size(); i < n; ++i) {
+ visibleLocalVariableAnnotations.get(i).accept(methodVisitor, true);
+ }
+ }
+ if (invisibleLocalVariableAnnotations != null) {
+ for (int i = 0, n = invisibleLocalVariableAnnotations.size(); i < n; ++i) {
+ invisibleLocalVariableAnnotations.get(i).accept(methodVisitor, false);
+ }
+ }
+ methodVisitor.visitMaxs(maxStack, maxLocals);
+ visited = true;
+ }
+ methodVisitor.visitEnd();
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java
new file mode 100644
index 00000000..f860d26d
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleExportNode.java
@@ -0,0 +1,83 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an exported package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleExportNode {
+
+ /**
+ * The internal name of the exported package (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ */
+ public String packaze;
+
+ /**
+ * The access flags (see {@link org.objectweb.asm.Opcodes}). Valid values are {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * The list of modules that can access this exported package, specified with fully qualified names
+ * (using dots). May be {@literal null}.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleExportNode}.
+ *
+ * @param packaze the internal name of the exported package (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param access the package access flags, one or more of {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ * @param modules a list of modules that can access this exported package, specified with fully
+ * qualified names (using dots).
+ */
+ public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this export declaration.
+ *
+ * @param moduleVisitor a module visitor.
+ */
+ public void accept(final ModuleVisitor moduleVisitor) {
+ moduleVisitor.visitExport(
+ packaze, access, modules == null ? null : modules.toArray(new String[0]));
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java
new file mode 100644
index 00000000..3f7a3305
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java
@@ -0,0 +1,245 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a module declaration.
+ *
+ * @author Remi Forax
+ */
+public class ModuleNode extends ModuleVisitor {
+
+ /** The fully qualified name (using dots) of this module. */
+ public String name;
+
+ /**
+ * The module's access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ */
+ public int access;
+
+ /** The version of this module. May be {@literal null}. */
+ public String version;
+
+ /**
+ * The internal name of the main class of this module (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public String mainClass;
+
+ /**
+ * The internal name of the packages declared by this module (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public List<String> packages;
+
+ /** The dependencies of this module. May be {@literal null}. */
+ public List<ModuleRequireNode> requires;
+
+ /** The packages exported by this module. May be {@literal null}. */
+ public List<ModuleExportNode> exports;
+
+ /** The packages opened by this module. May be {@literal null}. */
+ public List<ModuleOpenNode> opens;
+
+ /**
+ * The internal names of the services used by this module (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ */
+ public List<String> uses;
+
+ /** The services provided by this module. May be {@literal null}. */
+ public List<ModuleProvideNode> provides;
+
+ /**
+ * Constructs a {@link ModuleNode}. <i>Subclasses must not use this constructor</i>. Instead, they
+ * must use the {@link #ModuleNode(int,String,int,String,List,List,List,List,List)} version.
+ *
+ * @param name the fully qualified name (using dots) of the module.
+ * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ * @param version the module version, or {@literal null}.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public ModuleNode(final String name, final int access, final String version) {
+ super(/* latest api = */ Opcodes.ASM9);
+ if (getClass() != ModuleNode.class) {
+ throw new IllegalStateException();
+ }
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ }
+
+ // TODO(forax): why is there no 'mainClass' and 'packages' parameters in this constructor?
+ /**
+ * Constructs a {@link ModuleNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link
+ * Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ * @param name the fully qualified name (using dots) of the module.
+ * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ * @param version the module version, or {@literal null}.
+ * @param requires The dependencies of this module. May be {@literal null}.
+ * @param exports The packages exported by this module. May be {@literal null}.
+ * @param opens The packages opened by this module. May be {@literal null}.
+ * @param uses The internal names of the services used by this module (see {@link
+ * org.objectweb.asm.Type#getInternalName()}). May be {@literal null}.
+ * @param provides The services provided by this module. May be {@literal null}.
+ */
+ public ModuleNode(
+ final int api,
+ final String name,
+ final int access,
+ final String version,
+ final List<ModuleRequireNode> requires,
+ final List<ModuleExportNode> exports,
+ final List<ModuleOpenNode> opens,
+ final List<String> uses,
+ final List<ModuleProvideNode> provides) {
+ super(api);
+ this.name = name;
+ this.access = access;
+ this.version = version;
+ this.requires = requires;
+ this.exports = exports;
+ this.opens = opens;
+ this.uses = uses;
+ this.provides = provides;
+ }
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ if (packages == null) {
+ packages = new ArrayList<>(5);
+ }
+ packages.add(packaze);
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ if (requires == null) {
+ requires = new ArrayList<>(5);
+ }
+ requires.add(new ModuleRequireNode(module, access, version));
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ if (exports == null) {
+ exports = new ArrayList<>(5);
+ }
+ exports.add(new ModuleExportNode(packaze, access, Util.asArrayList(modules)));
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ if (opens == null) {
+ opens = new ArrayList<>(5);
+ }
+ opens.add(new ModuleOpenNode(packaze, access, Util.asArrayList(modules)));
+ }
+
+ @Override
+ public void visitUse(final String service) {
+ if (uses == null) {
+ uses = new ArrayList<>(5);
+ }
+ uses.add(service);
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ if (provides == null) {
+ provides = new ArrayList<>(5);
+ }
+ provides.add(new ModuleProvideNode(service, Util.asArrayList(providers)));
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ /**
+ * Makes the given class visitor visit this module.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ ModuleVisitor moduleVisitor = classVisitor.visitModule(name, access, version);
+ if (moduleVisitor == null) {
+ return;
+ }
+ if (mainClass != null) {
+ moduleVisitor.visitMainClass(mainClass);
+ }
+ if (packages != null) {
+ for (int i = 0, n = packages.size(); i < n; i++) {
+ moduleVisitor.visitPackage(packages.get(i));
+ }
+ }
+ if (requires != null) {
+ for (int i = 0, n = requires.size(); i < n; i++) {
+ requires.get(i).accept(moduleVisitor);
+ }
+ }
+ if (exports != null) {
+ for (int i = 0, n = exports.size(); i < n; i++) {
+ exports.get(i).accept(moduleVisitor);
+ }
+ }
+ if (opens != null) {
+ for (int i = 0, n = opens.size(); i < n; i++) {
+ opens.get(i).accept(moduleVisitor);
+ }
+ }
+ if (uses != null) {
+ for (int i = 0, n = uses.size(); i < n; i++) {
+ moduleVisitor.visitUse(uses.get(i));
+ }
+ }
+ if (provides != null) {
+ for (int i = 0, n = provides.size(); i < n; i++) {
+ provides.get(i).accept(moduleVisitor);
+ }
+ }
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java
new file mode 100644
index 00000000..fc73def3
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleOpenNode.java
@@ -0,0 +1,82 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an opened package with its name and the module that can access it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleOpenNode {
+
+ /**
+ * The internal name of the opened package (see {@link org.objectweb.asm.Type#getInternalName()}).
+ */
+ public String packaze;
+
+ /**
+ * The access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * The fully qualified names (using dots) of the modules that can use deep reflection to the
+ * classes of the open package, or {@literal null}.
+ */
+ public List<String> modules;
+
+ /**
+ * Constructs a new {@link ModuleOpenNode}.
+ *
+ * @param packaze the internal name of the opened package (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param access the access flag of the opened package, valid values are among {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param modules the fully qualified names (using dots) of the modules that can use deep
+ * reflection to the classes of the open package, or {@literal null}.
+ */
+ public ModuleOpenNode(final String packaze, final int access, final List<String> modules) {
+ this.packaze = packaze;
+ this.access = access;
+ this.modules = modules;
+ }
+
+ /**
+ * Makes the given module visitor visit this opened package.
+ *
+ * @param moduleVisitor a module visitor.
+ */
+ public void accept(final ModuleVisitor moduleVisitor) {
+ moduleVisitor.visitOpen(
+ packaze, access, modules == null ? null : modules.toArray(new String[0]));
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java
new file mode 100644
index 00000000..c0976d47
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleProvideNode.java
@@ -0,0 +1,69 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a service and its implementation provided by the current module.
+ *
+ * @author Remi Forax
+ */
+public class ModuleProvideNode {
+
+ /** The internal name of the service (see {@link org.objectweb.asm.Type#getInternalName()}). */
+ public String service;
+
+ /**
+ * The internal names of the implementations of the service (there is at least one provider). See
+ * {@link org.objectweb.asm.Type#getInternalName()}.
+ */
+ public List<String> providers;
+
+ /**
+ * Constructs a new {@link ModuleProvideNode}.
+ *
+ * @param service the internal name of the service.
+ * @param providers the internal names of the implementations of the service (there is at least
+ * one provider). See {@link org.objectweb.asm.Type#getInternalName()}.
+ */
+ public ModuleProvideNode(final String service, final List<String> providers) {
+ this.service = service;
+ this.providers = providers;
+ }
+
+ /**
+ * Makes the given module visitor visit this require declaration.
+ *
+ * @param moduleVisitor a module visitor.
+ */
+ public void accept(final ModuleVisitor moduleVisitor) {
+ moduleVisitor.visitProvide(service, providers.toArray(new String[0]));
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleRequireNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleRequireNode.java
new file mode 100644
index 00000000..27940d15
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleRequireNode.java
@@ -0,0 +1,73 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a required module with its name and access of a module descriptor.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRequireNode {
+
+ /** The fully qualified name (using dots) of the dependence. */
+ public String module;
+
+ /**
+ * The access flag of the dependence among {@code ACC_TRANSITIVE}, {@code ACC_STATIC_PHASE},
+ * {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /** The module version at compile time, or {@literal null}. */
+ public String version;
+
+ /**
+ * Constructs a new {@link ModuleRequireNode}.
+ *
+ * @param module the fully qualified name (using dots) of the dependence.
+ * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
+ * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param version the module version at compile time, or {@literal null}.
+ */
+ public ModuleRequireNode(final String module, final int access, final String version) {
+ this.module = module;
+ this.access = access;
+ this.version = version;
+ }
+
+ /**
+ * Makes the given module visitor visit this require directive.
+ *
+ * @param moduleVisitor a module visitor.
+ */
+ public void accept(final ModuleVisitor moduleVisitor) {
+ moduleVisitor.visitRequire(module, access, version);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/MultiANewArrayInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
new file mode 100644
index 00000000..f11f2187
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
@@ -0,0 +1,74 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a MULTIANEWARRAY instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class MultiANewArrayInsnNode extends AbstractInsnNode {
+
+ /** An array type descriptor (see {@link org.objectweb.asm.Type}). */
+ public String desc;
+
+ /** Number of dimensions of the array to allocate. */
+ public int dims;
+
+ /**
+ * Constructs a new {@link MultiANewArrayInsnNode}.
+ *
+ * @param descriptor an array type descriptor (see {@link org.objectweb.asm.Type}).
+ * @param numDimensions the number of dimensions of the array to allocate.
+ */
+ public MultiANewArrayInsnNode(final String descriptor, final int numDimensions) {
+ super(Opcodes.MULTIANEWARRAY);
+ this.desc = descriptor;
+ this.dims = numDimensions;
+ }
+
+ @Override
+ public int getType() {
+ return MULTIANEWARRAY_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitMultiANewArrayInsn(desc, dims);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ParameterNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ParameterNode.java
new file mode 100644
index 00000000..97ba8d2d
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ParameterNode.java
@@ -0,0 +1,68 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a parameter of a method.
+ *
+ * @author Remi Forax
+ */
+public class ParameterNode {
+
+ /** The parameter's name. */
+ public String name;
+
+ /**
+ * The parameter's access flags (see {@link org.objectweb.asm.Opcodes}). Valid values are {@code
+ * ACC_FINAL}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ */
+ public int access;
+
+ /**
+ * Constructs a new {@link ParameterNode}.
+ *
+ * @param access The parameter's access flags. Valid values are {@code ACC_FINAL}, {@code
+ * ACC_SYNTHETIC} or/and {@code ACC_MANDATED} (see {@link org.objectweb.asm.Opcodes}).
+ * @param name the parameter's name.
+ */
+ public ParameterNode(final String name, final int access) {
+ this.name = name;
+ this.access = access;
+ }
+
+ /**
+ * Makes the given visitor visit this parameter declaration.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitParameter(name, access);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/RecordComponentNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/RecordComponentNode.java
new file mode 100644
index 00000000..a1b58c66
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/RecordComponentNode.java
@@ -0,0 +1,204 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a record component.
+ *
+ * @author Remi Forax
+ */
+public class RecordComponentNode extends RecordComponentVisitor {
+
+ /** The record component name. */
+ public String name;
+
+ /** The record component descriptor (see {@link org.objectweb.asm.Type}). */
+ public String descriptor;
+
+ /** The record component signature. May be {@literal null}. */
+ public String signature;
+
+ /** The runtime visible annotations of this record component. May be {@literal null}. */
+ public List<AnnotationNode> visibleAnnotations;
+
+ /** The runtime invisible annotations of this record component. May be {@literal null}. */
+ public List<AnnotationNode> invisibleAnnotations;
+
+ /** The runtime visible type annotations of this record component. May be {@literal null}. */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /** The runtime invisible type annotations of this record component. May be {@literal null}. */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /** The non standard attributes of this record component. * May be {@literal null}. */
+ public List<Attribute> attrs;
+
+ /**
+ * Constructs a new {@link RecordComponentNode}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #RecordComponentNode(int, String, String, String)} version.
+ *
+ * @param name the record component name.
+ * @param descriptor the record component descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the record component signature.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public RecordComponentNode(final String name, final String descriptor, final String signature) {
+ this(/* latest api = */ Opcodes.ASM9, name, descriptor, signature);
+ if (getClass() != RecordComponentNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link RecordComponentNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
+ * or {@link Opcodes#ASM9}.
+ * @param name the record component name.
+ * @param descriptor the record component descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the record component signature.
+ */
+ public RecordComponentNode(
+ final int api, final String name, final String descriptor, final String signature) {
+ super(api);
+ this.name = name;
+ this.descriptor = descriptor;
+ this.signature = signature;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the FieldVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ AnnotationNode annotation = new AnnotationNode(descriptor);
+ if (visible) {
+ visibleAnnotations = Util.add(visibleAnnotations, annotation);
+ } else {
+ invisibleAnnotations = Util.add(invisibleAnnotations, annotation);
+ }
+ return annotation;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+ if (visible) {
+ visibleTypeAnnotations = Util.add(visibleTypeAnnotations, typeAnnotation);
+ } else {
+ invisibleTypeAnnotations = Util.add(invisibleTypeAnnotations, typeAnnotation);
+ }
+ return typeAnnotation;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ attrs = Util.add(attrs, attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accept methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Checks that this record component node is compatible with the given ASM API version. This
+ * method checks that this node, and all its children recursively, do not contain elements that
+ * were introduced in more recent versions of the ASM API than the given version.
+ *
+ * @param api an ASM API version. Must be one of {@link Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ */
+ public void check(final int api) {
+ if (api < Opcodes.ASM8) {
+ throw new UnsupportedClassVersionException();
+ }
+ }
+
+ /**
+ * Makes the given class visitor visit this record component.
+ *
+ * @param classVisitor a class visitor.
+ */
+ public void accept(final ClassVisitor classVisitor) {
+ RecordComponentVisitor recordComponentVisitor =
+ classVisitor.visitRecordComponent(name, descriptor, signature);
+ if (recordComponentVisitor == null) {
+ return;
+ }
+ // Visit the annotations.
+ if (visibleAnnotations != null) {
+ for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = visibleAnnotations.get(i);
+ annotation.accept(recordComponentVisitor.visitAnnotation(annotation.desc, true));
+ }
+ }
+ if (invisibleAnnotations != null) {
+ for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) {
+ AnnotationNode annotation = invisibleAnnotations.get(i);
+ annotation.accept(recordComponentVisitor.visitAnnotation(annotation.desc, false));
+ }
+ }
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ recordComponentVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ recordComponentVisitor.visitTypeAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ // Visit the non standard attributes.
+ if (attrs != null) {
+ for (int i = 0, n = attrs.size(); i < n; ++i) {
+ recordComponentVisitor.visitAttribute(attrs.get(i));
+ }
+ }
+ recordComponentVisitor.visitEnd();
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/TableSwitchInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/TableSwitchInsnNode.java
new file mode 100644
index 00000000..18418ff2
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/TableSwitchInsnNode.java
@@ -0,0 +1,93 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a TABLESWITCH instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class TableSwitchInsnNode extends AbstractInsnNode {
+
+ /** The minimum key value. */
+ public int min;
+
+ /** The maximum key value. */
+ public int max;
+
+ /** Beginning of the default handler block. */
+ public LabelNode dflt;
+
+ /** Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects. */
+ public List<LabelNode> labels;
+
+ /**
+ * Constructs a new {@link TableSwitchInsnNode}.
+ *
+ * @param min the minimum key value.
+ * @param max the maximum key value.
+ * @param dflt beginning of the default handler block.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code min + i} key.
+ */
+ public TableSwitchInsnNode(
+ final int min, final int max, final LabelNode dflt, final LabelNode... labels) {
+ super(Opcodes.TABLESWITCH);
+ this.min = min;
+ this.max = max;
+ this.dflt = dflt;
+ this.labels = Util.asArrayList(labels);
+ }
+
+ @Override
+ public int getType() {
+ return TABLESWITCH_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ Label[] labelsArray = new Label[this.labels.size()];
+ for (int i = 0, n = labelsArray.length; i < n; ++i) {
+ labelsArray[i] = this.labels.get(i).getLabel();
+ }
+ methodVisitor.visitTableSwitchInsn(min, max, dflt.getLabel(), labelsArray);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new TableSwitchInsnNode(min, max, clone(dflt, clonedLabels), clone(labels, clonedLabels))
+ .cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/TryCatchBlockNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/TryCatchBlockNode.java
new file mode 100644
index 00000000..30bfd698
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/TryCatchBlockNode.java
@@ -0,0 +1,127 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.List;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a try catch block.
+ *
+ * @author Eric Bruneton
+ */
+public class TryCatchBlockNode {
+
+ /** The beginning of the exception handler's scope (inclusive). */
+ public LabelNode start;
+
+ /** The end of the exception handler's scope (exclusive). */
+ public LabelNode end;
+
+ /** The beginning of the exception handler's code. */
+ public LabelNode handler;
+
+ /**
+ * The internal name of the type of exceptions handled by the handler. May be {@literal null} to
+ * catch any exceptions (for "finally" blocks).
+ */
+ public String type;
+
+ /** The runtime visible type annotations on the exception handler type. May be {@literal null}. */
+ public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+ /**
+ * The runtime invisible type annotations on the exception handler type. May be {@literal null}.
+ */
+ public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+ /**
+ * Constructs a new {@link TryCatchBlockNode}.
+ *
+ * @param start the beginning of the exception handler's scope (inclusive).
+ * @param end the end of the exception handler's scope (exclusive).
+ * @param handler the beginning of the exception handler's code.
+ * @param type the internal name of the type of exceptions handled by the handler (see {@link
+ * org.objectweb.asm.Type#getInternalName()}), or {@literal null} to catch any exceptions (for
+ * "finally" blocks).
+ */
+ public TryCatchBlockNode(
+ final LabelNode start, final LabelNode end, final LabelNode handler, final String type) {
+ this.start = start;
+ this.end = end;
+ this.handler = handler;
+ this.type = type;
+ }
+
+ /**
+ * Updates the index of this try catch block in the method's list of try catch block nodes. This
+ * index maybe stored in the 'target' field of the type annotations of this block.
+ *
+ * @param index the new index of this try catch block in the method's list of try catch block
+ * nodes.
+ */
+ public void updateIndex(final int index) {
+ int newTypeRef = 0x42000000 | (index << 8);
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ visibleTypeAnnotations.get(i).typeRef = newTypeRef;
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ invisibleTypeAnnotations.get(i).typeRef = newTypeRef;
+ }
+ }
+ }
+
+ /**
+ * Makes the given visitor visit this try catch block.
+ *
+ * @param methodVisitor a method visitor.
+ */
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitTryCatchBlock(
+ start.getLabel(), end.getLabel(), handler == null ? null : handler.getLabel(), type);
+ if (visibleTypeAnnotations != null) {
+ for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitTryCatchAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+ }
+ }
+ if (invisibleTypeAnnotations != null) {
+ for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+ TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+ typeAnnotation.accept(
+ methodVisitor.visitTryCatchAnnotation(
+ typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+ }
+ }
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java
new file mode 100644
index 00000000..967d2543
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A node that represents a type annotation.
+ *
+ * @author Eric Bruneton
+ */
+public class TypeAnnotationNode extends AnnotationNode {
+
+ /** A reference to the annotated type. See {@link org.objectweb.asm.TypeReference}. */
+ public int typeRef;
+
+ /**
+ * The path to the annotated type argument, wildcard bound, array element type, or static outer
+ * type within the referenced type. May be {@literal null} if the annotation targets 'typeRef' as
+ * a whole.
+ */
+ public TypePath typePath;
+
+ /**
+ * Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #TypeAnnotationNode(int, int, TypePath, String)} version.
+ *
+ * @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public TypeAnnotationNode(final int typeRef, final TypePath typePath, final String descriptor) {
+ this(/* latest api = */ Opcodes.ASM9, typeRef, typePath, descriptor);
+ if (getClass() != TypeAnnotationNode.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link AnnotationNode}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ */
+ public TypeAnnotationNode(
+ final int api, final int typeRef, final TypePath typePath, final String descriptor) {
+ super(api, descriptor);
+ this.typeRef = typeRef;
+ this.typePath = typePath;
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/TypeInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeInsnNode.java
new file mode 100644
index 00000000..d7459877
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeInsnNode.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a type instruction. A type instruction is an instruction which takes an
+ * internal name as parameter (see {@link org.objectweb.asm.Type#getInternalName()}).
+ *
+ * @author Eric Bruneton
+ */
+public class TypeInsnNode extends AbstractInsnNode {
+
+ /**
+ * The operand of this instruction. Despite its name (due to historical reasons), this operand is
+ * an internal name (see {@link org.objectweb.asm.Type#getInternalName()}).
+ */
+ public String desc;
+
+ /**
+ * Constructs a new {@link TypeInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This opcode must be NEW,
+ * ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param type the operand of the instruction to be constructed. This operand is an internal name
+ * (see {@link org.objectweb.asm.Type#getInternalName()}).
+ */
+ public TypeInsnNode(final int opcode, final String type) {
+ super(opcode);
+ this.desc = type;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be NEW, ANEWARRAY, CHECKCAST or
+ * INSTANCEOF.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitTypeInsn(opcode, desc);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new TypeInsnNode(opcode, desc).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/UnsupportedClassVersionException.java b/asm-tree/src/main/java/org/objectweb/asm/tree/UnsupportedClassVersionException.java
new file mode 100644
index 00000000..ee3b92a2
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/UnsupportedClassVersionException.java
@@ -0,0 +1,14 @@
+package org.objectweb.asm.tree;
+
+/**
+ * Exception thrown in {@link AnnotationNode#check}, {@link ClassNode#check}, {@link
+ * FieldNode#check} and {@link MethodNode#check} when these nodes (or their children, recursively)
+ * contain elements that were introduced in more recent versions of the ASM API than version passed
+ * to these methods.
+ *
+ * @author Eric Bruneton
+ */
+public class UnsupportedClassVersionException extends RuntimeException {
+
+ private static final long serialVersionUID = -3502347765891805831L;
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java b/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java
new file mode 100644
index 00000000..9b9085a5
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/Util.java
@@ -0,0 +1,163 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods to convert an array of primitive or object values to a mutable ArrayList, not
+ * baked by the array (unlike {@link java.util.Arrays#asList}).
+ *
+ * @author Eric Bruneton
+ */
+final class Util {
+
+ private Util() {}
+
+ static <T> List<T> add(final List<T> list, final T element) {
+ List<T> newList = list == null ? new ArrayList<>(1) : list;
+ newList.add(element);
+ return newList;
+ }
+
+ static <T> List<T> asArrayList(final int length) {
+ List<T> list = new ArrayList<>(length);
+ for (int i = 0; i < length; ++i) {
+ list.add(null);
+ }
+ return list;
+ }
+
+ static <T> List<T> asArrayList(final T[] array) {
+ if (array == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<T> list = new ArrayList<>(array.length);
+ for (T t : array) {
+ list.add(t); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return list;
+ }
+
+ static List<Byte> asArrayList(final byte[] byteArray) {
+ if (byteArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Byte> byteList = new ArrayList<>(byteArray.length);
+ for (byte b : byteArray) {
+ byteList.add(b); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return byteList;
+ }
+
+ static List<Boolean> asArrayList(final boolean[] booleanArray) {
+ if (booleanArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Boolean> booleanList = new ArrayList<>(booleanArray.length);
+ for (boolean b : booleanArray) {
+ booleanList.add(b); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return booleanList;
+ }
+
+ static List<Short> asArrayList(final short[] shortArray) {
+ if (shortArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Short> shortList = new ArrayList<>(shortArray.length);
+ for (short s : shortArray) {
+ shortList.add(s); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return shortList;
+ }
+
+ static List<Character> asArrayList(final char[] charArray) {
+ if (charArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Character> charList = new ArrayList<>(charArray.length);
+ for (char c : charArray) {
+ charList.add(c); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return charList;
+ }
+
+ static List<Integer> asArrayList(final int[] intArray) {
+ if (intArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Integer> intList = new ArrayList<>(intArray.length);
+ for (int i : intArray) {
+ intList.add(i); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return intList;
+ }
+
+ static List<Float> asArrayList(final float[] floatArray) {
+ if (floatArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Float> floatList = new ArrayList<>(floatArray.length);
+ for (float f : floatArray) {
+ floatList.add(f); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return floatList;
+ }
+
+ static List<Long> asArrayList(final long[] longArray) {
+ if (longArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Long> longList = new ArrayList<>(longArray.length);
+ for (long l : longArray) {
+ longList.add(l); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return longList;
+ }
+
+ static List<Double> asArrayList(final double[] doubleArray) {
+ if (doubleArray == null) {
+ return new ArrayList<>();
+ }
+ ArrayList<Double> doubleList = new ArrayList<>(doubleArray.length);
+ for (double d : doubleArray) {
+ doubleList.add(d); // NOPMD(UseArraysAsList): we want a modifiable list.
+ }
+ return doubleList;
+ }
+
+ static <T> List<T> asArrayList(final int length, final T[] array) {
+ List<T> list = new ArrayList<>(length);
+ for (int i = 0; i < length; ++i) {
+ list.add(array[i]); // NOPMD(UseArraysAsList): we convert a part of the array.
+ }
+ return list;
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/VarInsnNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/VarInsnNode.java
new file mode 100644
index 00000000..95d2df9b
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/VarInsnNode.java
@@ -0,0 +1,82 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import java.util.Map;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a local variable instruction. A local variable instruction is an
+ * instruction that loads or stores the value of a local variable.
+ *
+ * @author Eric Bruneton
+ */
+public class VarInsnNode extends AbstractInsnNode {
+
+ /** The operand of this instruction. This operand is the index of a local variable. */
+ public int var;
+
+ /**
+ * Constructs a new {@link VarInsnNode}.
+ *
+ * @param opcode the opcode of the local variable instruction to be constructed. This opcode must
+ * be ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param varIndex the operand of the instruction to be constructed. This operand is the index of
+ * a local variable.
+ */
+ public VarInsnNode(final int opcode, final int varIndex) {
+ super(opcode);
+ this.var = varIndex;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
+ * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ @Override
+ public int getType() {
+ return VAR_INSN;
+ }
+
+ @Override
+ public void accept(final MethodVisitor methodVisitor) {
+ methodVisitor.visitVarInsn(opcode, var);
+ acceptAnnotations(methodVisitor);
+ }
+
+ @Override
+ public AbstractInsnNode clone(final Map<LabelNode, LabelNode> clonedLabels) {
+ return new VarInsnNode(opcode, var).cloneAnnotations(this);
+ }
+}
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/package.html b/asm-tree/src/main/java/org/objectweb/asm/tree/package.html
new file mode 100644
index 00000000..9e7cd7a9
--- /dev/null
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/package.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm.tree</title>
+</head>
+<body>
+
+<p>
+Provides an ASM visitor that constructs a tree representation of the
+classes it visits. This class adapter can be useful to implement "complex"
+class manipulation operations, i.e., operations that would be very hard to
+implement without using a tree representation (such as optimizing the number
+of local variables used by a method).
+</p>
+
+<p>
+However, this class adapter has a cost: it makes ASM bigger and slower. Indeed
+it requires more than twenty new classes, and multiplies the time needed to
+transform a class by almost two (it is almost two times faster to read, "modify"
+and write a class with a ClassVisitor than with a ClassNode). This is why
+this package is bundled in an optional <code>asm-tree.jar</code> library that
+is separated from (but requires) the <code>asm.jar</code> library, which contains
+the core ASM framework. This is also why <em>it is recommended not to use this
+class adapter when it is possible</em>.
+</p>
+
+<p>
+The root class is the ClassNode, that can be created from existing bytecode. For example:
+</p>
+
+<pre>
+ ClassReader classReader = new ClassReader(source);
+ ClassNode classNode = new ClassNode();
+ classReader.accept(classNode, 0);
+</pre>
+
+<p>
+Now the content of ClassNode can be modified and then
+serialized back into bytecode:
+</p>
+
+<pre>
+ ClassWriter classWriter = new ClassWriter(0);
+ classNode.accept(classWriter);
+</pre>
+
+<p>
+Using a simple ClassVisitor it is possible to create MethodNode instances per-method.
+In this example MethodNode is acting as a buffer that is flushed out at visitEnd() call:
+</p>
+
+<pre>
+ ClassReader classReader = new ClassReader(source);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor classVisitor = new ClassVisitor(ASM7, classWriter) {
+ public MethodVisitor visitMethod(int access, String name,
+ String desc, String signature, String[] exceptions) {
+ final MethodVisitor methodVisitor =
+ super.visitMethod(access, name, desc, signature, exceptions);
+ MethodNode methodNode = new MethodNode(access, name, desc, signature, exceptions) {
+ public void visitEnd() {
+ // transform or analyze method code using tree API
+ accept(methodVisitor);
+ }
+ };
+ }
+ };
+ classReader.accept(classVisitor, 0);
+</pre>
+
+<p>
+Several strategies can be used to construct method code from scratch. The first
+option is to create a MethodNode, and then create XxxInsnNode instances and
+add them to the instructions list:
+</p>
+
+<pre>
+MethodNode methodNode = new MethodNode(...);
+methodNode.instructions.add(new VarInsnNode(ALOAD, 0));
+...
+</pre>
+
+<p>
+Alternatively, you can use the fact that MethodNode is a MethodVisitor, and use
+that to create the XxxInsnNode and add them to the instructions list through
+the standard MethodVisitor methods:
+</p>
+
+<pre>
+MethodNode methodNode = new MethodNode(...);
+methodNode.visitVarInsn(ALOAD, 0);
+...
+</pre>
+
+<p>
+If you cannot generate all the instructions in sequential order, i.e. if you
+need to save some pointer in the instruction list and then insert instructions
+at that place after other instructions have been generated, you can use InsnList
+methods insert() and insertBefore() to insert instructions at a saved pointer.
+</p>
+
+<pre>
+MethodNode methodNode = new MethodNode(...);
+methodNode.visitVarInsn(ALOAD, 0);
+AbstractInsnNode ptr = methodNode.instructions.getLast();
+methodNode.visitVarInsn(ALOAD, 1);
+// inserts an instruction between ALOAD 0 and ALOAD 1
+methodNode.instructions.insert(ptr, new VarInsnNode(ALOAD, 0));
+...
+</pre>
+
+<p>
+If you need to insert instructions while iterating over an existing instruction
+list, you can also use several strategies. The first one is to use a
+ListIterator over the instruction list:
+</p>
+
+<pre>
+ListIterator it = methodNode.instructions.iterator();
+while (it.hasNext()) {
+ AbstractInsnNode insnNode = (AbstractInsnNode) it.next();
+ if (...) {
+ it.add(new VarInsnNode(ALOAD, 0));
+ }
+}
+</pre>
+
+<p>
+It is also possible to convert an instruction list into an array and iterate through
+array elements:
+</p>
+
+<pre>
+AbstractInsnNode[] insns = methodNode.instructions.toArray();
+for(int i = 0; i&lt;insns.length; i++) {
+ AbstractInsnNode insn = insns[i];
+ if (...) {
+ methodNode.instructions.insert(insn, new VarInsnNode(ALOAD, 0));
+ }
+}
+</pre>
+
+<p>
+If you want to insert these instructions through the MethodVisitor methods,
+you can use another instance of MethodNode as a MethodVisitor and then
+insert instructions collected by that instance into the instruction list.
+For example:
+</p>
+
+<pre>
+AbstractInsnNode[] insns = methodNode.instructions.toArray();
+for(int i = 0; i&lt;insns.length; i++) {
+ AbstractInsnNode insn = insns[i];
+ if (...) {
+ MethodNode toInsert = new MethodNode();
+ toInsert.visitVarInsn(ALOAD, 0);
+ toInsert.visitVarInsn(ALOAD, 1);
+ m.instructions.insert(insn, toInsert.instructions);
+ }
+}
+</pre>
+
+<p>
+@since ASM 1.3.3
+</p>
+
+</body>
+</html>
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java
new file mode 100644
index 00000000..e926dbcc
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java
@@ -0,0 +1,123 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link AnnotationNode}.
+ *
+ * @author Eric Bruneton
+ */
+class AnnotationNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ AnnotationNode annotationNode = new AnnotationNode("LI;");
+
+ assertEquals("LI;", annotationNode.desc);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new AnnotationNode("LI;") {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+
+ @Test
+ void testVisit() {
+ AnnotationNode annotationNode = new AnnotationNode("LI;");
+
+ annotationNode.visit("bytes", new byte[] {0, 1});
+ annotationNode.visit("booleans", new boolean[] {false, true});
+ annotationNode.visit("shorts", new short[] {0, 1});
+ annotationNode.visit("chars", new char[] {'0', '1'});
+ annotationNode.visit("ints", new int[] {0, 1});
+ annotationNode.visit("longs", new long[] {0L, 1L});
+ annotationNode.visit("floats", new float[] {0.0f, 1.0f});
+ annotationNode.visit("doubles", new double[] {0.0, 1.0});
+ annotationNode.visit("string", "value");
+ annotationNode.visitAnnotation("annotation", "Lpkg/Annotation;");
+
+ assertEquals("bytes", annotationNode.values.get(0));
+ assertEquals(Arrays.asList(new Byte[] {0, 1}), annotationNode.values.get(1));
+ assertEquals("booleans", annotationNode.values.get(2));
+ assertEquals(Arrays.asList(new Boolean[] {false, true}), annotationNode.values.get(3));
+ assertEquals("shorts", annotationNode.values.get(4));
+ assertEquals(Arrays.asList(new Short[] {0, 1}), annotationNode.values.get(5));
+ assertEquals("chars", annotationNode.values.get(6));
+ assertEquals(Arrays.asList(new Character[] {'0', '1'}), annotationNode.values.get(7));
+ assertEquals("ints", annotationNode.values.get(8));
+ assertEquals(Arrays.asList(new Integer[] {0, 1}), annotationNode.values.get(9));
+ assertEquals("longs", annotationNode.values.get(10));
+ assertEquals(Arrays.asList(new Long[] {0L, 1L}), annotationNode.values.get(11));
+ assertEquals("floats", annotationNode.values.get(12));
+ assertEquals(Arrays.asList(new Float[] {0.0f, 1.0f}), annotationNode.values.get(13));
+ assertEquals("doubles", annotationNode.values.get(14));
+ assertEquals(Arrays.asList(new Double[] {0.0, 1.0}), annotationNode.values.get(15));
+ assertEquals("string", annotationNode.values.get(16));
+ assertEquals("value", annotationNode.values.get(17));
+ assertEquals("annotation", annotationNode.values.get(18));
+ assertEquals("Lpkg/Annotation;", ((AnnotationNode) annotationNode.values.get(19)).desc);
+ }
+
+ @Test
+ void testAnnotationNode_accept_skipNestedAnnotations() {
+ AnnotationNode annotationNode = new AnnotationNode("LI;");
+ annotationNode.visit("bytes", new byte[] {0, 1});
+ annotationNode.visitAnnotation("annotation", "Lpkg/Annotation;");
+ AnnotationNode dstAnnotationNode = new AnnotationNode("LJ;");
+ AnnotationVisitor skipNestedAnnotationsVisitor =
+ new AnnotationVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL, dstAnnotationNode) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ return null;
+ }
+ };
+
+ annotationNode.accept(skipNestedAnnotationsVisitor);
+
+ assertNull(dstAnnotationNode.values);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java
new file mode 100644
index 00000000..c51a041d
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java
@@ -0,0 +1,249 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link ClassNode}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ ClassNode classNode = new ClassNode();
+
+ assertTrue(classNode.interfaces.isEmpty());
+ assertTrue(classNode.innerClasses.isEmpty());
+ assertTrue(classNode.fields.isEmpty());
+ assertTrue(classNode.methods.isEmpty());
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new ClassNode() {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+
+ /**
+ * Tests that {@link ClassNode#check} throws an exception for classes that contain elements more
+ * recent than the ASM API version.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testCheck(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassNode classNode = new ClassNode(apiParameter.value()) {};
+ new ClassReader(classParameter.getBytes()).accept(classNode, attributes(), 0);
+
+ Executable check = () -> classNode.check(apiParameter.value());
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ assertThrows(UnsupportedClassVersionException.class, check);
+ } else {
+ assertDoesNotThrow(check);
+ }
+ }
+
+ /** Tests that classes are unchanged with a ClassReader->ClassNode->ClassWriter transform. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testVisitAndAccept(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassNode classNode = new ClassNode(apiParameter.value()) {};
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classNode, attributes(), 0);
+ classNode.accept(classWriter);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that classes are unchanged with a ClassReader->ClassNode->ClassWriter transform, when all
+ * instructions are cloned.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testVisitAndAccept_cloneInstructions(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassNode classNode = new ClassNode(apiParameter.value()) {};
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classNode, attributes(), 0);
+ for (MethodNode methodNode : classNode.methods) {
+ cloneInstructions(methodNode);
+ }
+ classNode.accept(classWriter);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /** Tests that ClassNode accepts visitors that remove class elements. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testVisitAndAccept_removeMembersVisitor(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassNode classNode = new ClassNode(apiParameter.value()) {};
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classNode, attributes(), 0);
+ classNode.accept(new RemoveMembersClassVisitor(apiParameter.value(), classWriter));
+
+ ClassWriter expectedClassWriter = new ClassWriter(0);
+ classReader.accept(new RemoveMembersClassVisitor(apiParameter.value(), expectedClassWriter), 0);
+ assertEquals(
+ new ClassFile(expectedClassWriter.toByteArray()), new ClassFile(classWriter.toByteArray()));
+ }
+
+ private static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ @SuppressWarnings("serial")
+ private static void cloneInstructions(final MethodNode methodNode) {
+ Map<LabelNode, LabelNode> labelCloneMap =
+ new HashMap<LabelNode, LabelNode>() {
+ @Override
+ public LabelNode get(final Object o) {
+ return (LabelNode) o;
+ }
+ };
+ Iterator<AbstractInsnNode> insnIterator = methodNode.instructions.iterator();
+ while (insnIterator.hasNext()) {
+ AbstractInsnNode insn = insnIterator.next();
+ methodNode.instructions.set(insn, insn.clone(labelCloneMap));
+ }
+ }
+
+ private static class RemoveMembersClassVisitor extends ClassVisitor {
+
+ RemoveMembersClassVisitor(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ super.visit(version, access & ~Opcodes.ACC_RECORD, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ return null;
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {}
+
+ @Override
+ public void visitNestMember(final String nestMember) {}
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {}
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {}
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ return null;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return null;
+ }
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/CodeComment.java b/asm-tree/src/test/java/org/objectweb/asm/tree/CodeComment.java
new file mode 100644
index 00000000..fcfe0f89
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/CodeComment.java
@@ -0,0 +1,77 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard code attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class CodeComment extends Attribute {
+
+ public CodeComment() {
+ super("CodeComment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new CodeComment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/Comment.java b/asm-tree/src/test/java/org/objectweb/asm/tree/Comment.java
new file mode 100644
index 00000000..5cff6065
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/Comment.java
@@ -0,0 +1,72 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class Comment extends Attribute {
+
+ public Comment() {
+ super("Comment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new Comment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/FieldInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/FieldInsnNodeTest.java
new file mode 100644
index 00000000..4599ae14
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/FieldInsnNodeTest.java
@@ -0,0 +1,62 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link FieldInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class FieldInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ FieldInsnNode fieldInsnNode = new FieldInsnNode(Opcodes.GETSTATIC, "owner", "name", "I");
+
+ assertEquals(AbstractInsnNode.FIELD_INSN, fieldInsnNode.getType());
+ assertEquals(Opcodes.GETSTATIC, fieldInsnNode.getOpcode());
+ assertEquals("owner", fieldInsnNode.owner);
+ assertEquals("name", fieldInsnNode.name);
+ assertEquals("I", fieldInsnNode.desc);
+ }
+
+ @Test
+ void testSetOpcode() {
+ FieldInsnNode fieldInsnNode = new FieldInsnNode(Opcodes.GETSTATIC, "owner", "name", "I");
+
+ fieldInsnNode.setOpcode(Opcodes.PUTSTATIC);
+
+ assertEquals(Opcodes.PUTSTATIC, fieldInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/FieldNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/FieldNodeTest.java
new file mode 100644
index 00000000..e591dee9
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/FieldNodeTest.java
@@ -0,0 +1,59 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link FieldNode}.
+ *
+ * @author Eric Bruneton
+ */
+class FieldNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ FieldNode fieldNode = new FieldNode(123, "field", "I", null, null);
+
+ assertEquals(123, fieldNode.access);
+ assertEquals("field", fieldNode.name);
+ assertEquals("I", fieldNode.desc);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new FieldNode(123, "field", "I", null, null) {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/FrameNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/FrameNodeTest.java
new file mode 100644
index 00000000..b00024cf
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/FrameNodeTest.java
@@ -0,0 +1,65 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link FrameNode}.
+ *
+ * @author Eric Bruneton
+ */
+class FrameNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ Object[] locals = new Object[] {"l"};
+ Object[] stack = new Object[] {"s", "t"};
+
+ FrameNode frameNode = new FrameNode(Opcodes.F_FULL, 1, locals, 2, stack);
+
+ assertEquals(AbstractInsnNode.FRAME, frameNode.getType());
+ assertEquals(Opcodes.F_FULL, frameNode.type);
+ assertEquals(Arrays.asList(locals), frameNode.local);
+ assertEquals(Arrays.asList(stack), frameNode.stack);
+ }
+
+ @Test
+ void testConstructor_illegalArgument() {
+ Executable constructor = () -> new FrameNode(Integer.MAX_VALUE, 0, null, 0, null);
+
+ assertThrows(IllegalArgumentException.class, constructor);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/IincInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/IincInsnNodeTest.java
new file mode 100644
index 00000000..170cf2f0
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/IincInsnNodeTest.java
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link IincInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class IincInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ IincInsnNode iincnInsnNode = new IincInsnNode(1, 2);
+
+ assertEquals(AbstractInsnNode.IINC_INSN, iincnInsnNode.getType());
+ assertEquals(1, iincnInsnNode.var);
+ assertEquals(2, iincnInsnNode.incr);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java
new file mode 100644
index 00000000..93f033a0
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java
@@ -0,0 +1,973 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link InsnList}.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+class InsnListTest {
+
+ private final InsnNode insn1 = new InsnNode(0);
+ private final InsnNode insn2 = new InsnNode(1);
+
+ @Test
+ void testSize_emptyList() {
+ assertEquals(0, newInsnList().size());
+ }
+
+ @Test
+ void testGetFirst_emptyList() {
+ assertEquals(null, newInsnList().getFirst());
+ }
+
+ @Test
+ void testGetLast_emptyList() {
+ assertEquals(null, newInsnList().getLast());
+ }
+
+ @Test
+ void testGet_outOfBounds() {
+ Executable get = () -> newInsnList().get(0);
+
+ assertThrows(IndexOutOfBoundsException.class, get);
+ }
+
+ @Test
+ void testContains() {
+ assertFalse(newInsnList().contains(new InsnNode(0)));
+ }
+
+ @Test
+ void testIndexOf_noSuchElement() {
+ InsnList insnList = newInsnList();
+
+ Executable indexOf = () -> insnList.indexOf(new InsnNode(0));
+
+ assertThrows(NoSuchElementException.class, indexOf);
+ }
+
+ @Test
+ void testIndexOf() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ int index1 = insnList.indexOf(insn1);
+ int index2 = insnList.indexOf(insn2);
+
+ assertEquals(0, index1);
+ assertEquals(1, index2);
+ }
+
+ @Test
+ void testAccept_cloneListVisitor() {
+ InsnList insnList = newInsnList();
+ insnList.add(new InsnNode(55));
+ insnList.add(new InsnNode(77));
+ InsnList dstInsnList = new InsnList();
+
+ insnList.accept(
+ new MethodVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+ @Override
+ public void visitInsn(final int opcode) {
+ dstInsnList.add(new InsnNode(opcode));
+ }
+ });
+
+ assertEquals(2, dstInsnList.size());
+ assertEquals(55, dstInsnList.get(0).opcode);
+ assertEquals(77, dstInsnList.get(1).opcode);
+ }
+
+ @Test
+ void testIteratorNext_noSuchElement() {
+ ListIterator<AbstractInsnNode> iterator = newInsnList().iterator();
+
+ Executable next = () -> iterator.next();
+
+ assertThrows(NoSuchElementException.class, next);
+ }
+
+ @Test
+ void testIteratorNext_nonEmptyList() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+
+ AbstractInsnNode insn = iterator.next();
+
+ assertEquals(insn2, insn);
+ assertFalse(iterator.hasNext());
+ assertEquals(2, iterator.nextIndex());
+ assertTrue(iterator.hasPrevious());
+ assertEquals(1, iterator.previousIndex());
+ }
+
+ @Test
+ void testIteratorPrevious_noSuchElement() {
+ ListIterator<AbstractInsnNode> iterator = newInsnList().iterator();
+
+ Executable previous = () -> iterator.previous();
+
+ assertThrows(NoSuchElementException.class, previous);
+ }
+
+ @Test
+ void testIteratorPrevious_nonEmptyList() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+
+ AbstractInsnNode insn = iterator.previous();
+
+ assertEquals(insn1, insn);
+ assertTrue(iterator.hasNext());
+ assertEquals(0, iterator.nextIndex());
+ assertFalse(iterator.hasPrevious());
+ assertEquals(-1, iterator.previousIndex());
+ }
+
+ @Test
+ void testIteratorAdd_emptyList() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList();
+
+ insnList.iterator().add(insn);
+
+ assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorAdd_firstInsn() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+
+ iterator.add(insn);
+
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorRemove_illegalState() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+
+ Executable remove = () -> iterator.remove();
+
+ assertThrows(IllegalStateException.class, remove);
+ }
+
+ @Test
+ void testIteratorRemove_afterNext() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+ iterator.next();
+
+ iterator.remove();
+
+ assertArrayEquals(new AbstractInsnNode[] {insn1}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorRemove_afterPrevious() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+ iterator.previous();
+
+ iterator.remove();
+
+ assertArrayEquals(new AbstractInsnNode[] {insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorAdd_lastInsn() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(2);
+
+ iterator.add(insn);
+
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorSet_illegalState() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+
+ Executable set = () -> iterator.set(insn);
+
+ assertThrows(IllegalStateException.class, set);
+ }
+
+ @Test
+ void testIteratorSet_afterNext() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+ iterator.next();
+
+ iterator.set(insn);
+
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn}, insnList.toArray());
+ }
+
+ @Test
+ void testIteratorSet_afterPrevious() {
+ InsnNode insn = new InsnNode(0);
+ InsnList insnList = newInsnList(insn1, insn2);
+ ListIterator<AbstractInsnNode> iterator = insnList.iterator(1);
+ iterator.previous();
+
+ iterator.set(insn);
+
+ assertArrayEquals(new AbstractInsnNode[] {insn, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testIterator_cacheIsNull() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ insnList.iterator();
+ assertNull(insnList.cache);
+ }
+
+ @Test
+ void testToArray_emptyList() {
+ assertEquals(0, newInsnList().toArray().length);
+ }
+
+ @Test
+ void testToArray_nonEmptyList() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ AbstractInsnNode[] insnArray = insnList.toArray();
+
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnArray);
+ }
+
+ @Test
+ void testSet_noSuchElement() {
+ InsnList insnList = newInsnList();
+
+ Executable set = () -> insnList.set(new InsnNode(0), new InsnNode(0));
+
+ assertThrows(NoSuchElementException.class, set);
+ }
+
+ @Test
+ void testSet_singleInsn() {
+ InsnList insnList = newInsnList();
+ insnList.add(insn1);
+ AbstractInsnNode insn = new InsnNode(0);
+
+ insnList.set(insn1, insn);
+
+ assertEquals(1, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ }
+
+ @Test
+ void testSet_firstInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ AbstractInsnNode insn = new InsnNode(0);
+
+ insnList.set(insn1, insn);
+
+ assertEquals(2, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ }
+
+ @Test
+ void testSet_lastInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ AbstractInsnNode insn = new InsnNode(0);
+ insnList.toArray();
+
+ insnList.set(insn2, insn);
+
+ assertEquals(2, insnList.size());
+ assertEquals(insn, insnList.getLast());
+ }
+
+ @Test
+ void testAdd_illegalArgument() {
+ InsnList insnList = newInsnList();
+ newInsnList(insn1, insn2);
+
+ Executable add = () -> insnList.add(insn1);
+
+ assertThrows(IllegalArgumentException.class, add);
+ }
+
+ @Test
+ void testAdd_inEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+
+ insnList.add(insn);
+
+ assertEquals(1, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(0, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray());
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testAdd_inNonEmptyList() {
+ InsnList insnList = newInsnList();
+ insnList.add(insn1);
+ InsnNode insn = new InsnNode(0);
+
+ insnList.add(insn);
+
+ assertEquals(2, insnList.size());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(1, insnList.indexOf(insn));
+ assertEquals(insn, insnList.get(1));
+ assertTrue(insnList.contains(insn));
+ }
+
+ @Test
+ void testAddList_illegalArgument() {
+ InsnList insnList = newInsnList();
+
+ Executable add = () -> insnList.add(insnList);
+
+ assertThrows(IllegalArgumentException.class, add);
+ }
+
+ @Test
+ void testAddList_inEmptyList_emptyList() {
+ InsnList insnList = newInsnList();
+
+ insnList.add(newInsnList());
+
+ assertEquals(0, insnList.size());
+ assertEquals(null, insnList.getFirst());
+ assertEquals(null, insnList.getLast());
+ assertArrayEquals(new AbstractInsnNode[0], insnList.toArray());
+ }
+
+ @Test
+ void testAddList_inEmptyList_nonEmptyList() {
+ InsnList insnList = newInsnList();
+
+ insnList.add(newInsnList(insn1, insn2));
+
+ assertEquals(2, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn1));
+ assertEquals(1, insnList.indexOf(insn2));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testAddList_inNonEmptyList_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.add(newInsnList(insn1, insn2));
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn));
+ assertEquals(1, insnList.indexOf(insn1));
+ assertEquals(2, insnList.indexOf(insn2));
+ assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsert_illegalArgument() {
+ InsnList insnList = newInsnList();
+ newInsnList(insn1, insn2);
+
+ Executable insert = () -> insnList.insert(insn1);
+
+ assertThrows(IllegalArgumentException.class, insert);
+ }
+
+ @Test
+ void testInsert_inEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+
+ insnList.insert(insn);
+
+ assertEquals(1, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(0, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsert_inNonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(new InsnNode(0));
+
+ insnList.insert(insn);
+
+ assertEquals(2, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(0, insnList.indexOf(insn));
+ }
+
+ @Test
+ void testInsertList_illegalArgument() {
+ InsnList insnList = newInsnList();
+
+ Executable insert = () -> insnList.insert(insnList);
+
+ assertThrows(IllegalArgumentException.class, insert);
+ }
+
+ @Test
+ void testInsertList_inEmptyList_emptyList() {
+ InsnList insnList = newInsnList();
+
+ insnList.insert(newInsnList());
+
+ assertEquals(0, insnList.size());
+ assertEquals(null, insnList.getFirst());
+ assertEquals(null, insnList.getLast());
+ assertArrayEquals(new AbstractInsnNode[0], insnList.toArray());
+ }
+
+ @Test
+ void testInsertList_inEmptyList_nonEmptyList() {
+ InsnList insnList = newInsnList();
+
+ insnList.insert(newInsnList(insn1, insn2));
+
+ assertEquals(2, insnList.size(), 2);
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn1));
+ assertEquals(1, insnList.indexOf(insn2));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertList_inNonEmptyList_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.insert(newInsnList(insn1, insn2));
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn1));
+ assertEquals(1, insnList.indexOf(insn2));
+ assertEquals(2, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertAfter_noSuchElement() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ Executable insert = () -> insnList.insert(new InsnNode(0), new InsnNode(0));
+
+ assertThrows(NoSuchElementException.class, insert);
+ }
+
+ @Test
+ void testInsertAfter_lastInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ InsnNode insn = new InsnNode(0);
+
+ insnList.insert(insn2, insn);
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(2, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertAfter_notLastInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ InsnNode insn = new InsnNode(0);
+
+ insnList.insert(insn1, insn);
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(1, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListAfter_noSuchElement() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ Executable insert = () -> insnList.insert(new InsnNode(0), newInsnList());
+
+ assertThrows(NoSuchElementException.class, insert);
+ }
+
+ @Test
+ void testInsertListAfter_lastInsn_emptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.insert(insn, newInsnList());
+
+ assertEquals(1, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListAfter_lastInsn_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.insert(insn, newInsnList(insn1, insn2));
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn));
+ assertEquals(1, insnList.indexOf(insn1));
+ assertEquals(2, insnList.indexOf(insn2));
+ assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListAfter_notLastInsn_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+ insnList.add(new InsnNode(0));
+
+ insnList.insert(insn, newInsnList(insn1, insn2));
+
+ assertEquals(4, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(0, insnList.indexOf(insn));
+ assertEquals(1, insnList.indexOf(insn1));
+ assertEquals(2, insnList.indexOf(insn2));
+ }
+
+ @Test
+ void testInsertBefore_noSuchElement() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ Executable insertBefore = () -> insnList.insertBefore(new InsnNode(0), new InsnNode(0));
+
+ assertThrows(NoSuchElementException.class, insertBefore);
+ }
+
+ @Test
+ void testInsertBefore_firstInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ InsnNode insn = new InsnNode(0);
+
+ insnList.insertBefore(insn1, insn);
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertEquals(0, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertBefore_notFirstInsn() {
+ InsnList insnList = newInsnList(insn1, insn2);
+ InsnNode insn = new InsnNode(0);
+
+ insnList.insertBefore(insn2, insn);
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn2, insnList.getLast());
+ assertEquals(insn, insnList.get(1));
+ assertTrue(insnList.contains(insn));
+ assertEquals(1, insnList.indexOf(insn));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListBefore_noSuchElement() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ Executable insertBefore = () -> insnList.insertBefore(new InsnNode(0), newInsnList());
+
+ assertThrows(NoSuchElementException.class, insertBefore);
+ }
+
+ @Test
+ void testInsertListBefore_firstInsn_emptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.insertBefore(insn, newInsnList());
+
+ assertEquals(1, insnList.size());
+ assertEquals(insn, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListBefore_firstInsn_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.insertBefore(insn, newInsnList(insn1, insn2));
+
+ assertEquals(3, insnList.size());
+ assertEquals(insn1, insnList.getFirst());
+ assertEquals(insn, insnList.getLast());
+ assertEquals(insn1, insnList.get(0));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(2, insnList.indexOf(insn));
+ assertEquals(0, insnList.indexOf(insn1));
+ assertEquals(1, insnList.indexOf(insn2));
+ assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray());
+ }
+
+ @Test
+ void testInsertListBefore_notFirstInsn_nonEmptyList() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(new InsnNode(0));
+ insnList.add(insn);
+
+ insnList.insertBefore(insn, newInsnList(insn1, insn2));
+
+ assertEquals(4, insnList.size());
+ assertEquals(insn1, insnList.get(1));
+ assertEquals(insn2, insnList.get(2));
+ assertTrue(insnList.contains(insn));
+ assertTrue(insnList.contains(insn1));
+ assertTrue(insnList.contains(insn2));
+ assertEquals(3, insnList.indexOf(insn));
+ assertEquals(1, insnList.indexOf(insn1));
+ assertEquals(2, insnList.indexOf(insn2));
+ }
+
+ @Test
+ void testRemove_noSuchElement() {
+ InsnList insnList = newInsnList(insn1, insn2);
+
+ Executable remove = () -> insnList.remove(new InsnNode(0));
+
+ assertThrows(NoSuchElementException.class, remove);
+ }
+
+ @Test
+ void testRemove_singleInsn() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+
+ insnList.remove(insn);
+
+ assertEquals(0, insnList.size());
+ assertEquals(null, insnList.getFirst());
+ assertEquals(null, insnList.getLast());
+ assertFalse(insnList.contains(insn));
+ assertArrayEquals(new AbstractInsnNode[0], insnList.toArray());
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testRemove_firstInsn() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(insn);
+ insnList.add(new InsnNode(0));
+
+ insnList.remove(insn);
+
+ assertFalse(insnList.contains(insn));
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testRemove_middleInsn() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(new InsnNode(0));
+ insnList.add(insn);
+ insnList.add(new InsnNode(0));
+
+ insnList.remove(insn);
+
+ assertFalse(insnList.contains(insn));
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testRemove_lastInsn() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(new InsnNode(0));
+ insnList.add(insn);
+
+ insnList.remove(insn);
+
+ assertFalse(insnList.contains(insn));
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testClear() {
+ InsnList insnList = newInsnList();
+ InsnNode insn = new InsnNode(0);
+ insnList.add(new InsnNode(0));
+ insnList.add(insn);
+ insnList.add(new InsnNode(0));
+
+ insnList.clear();
+
+ assertEquals(0, insnList.size());
+ assertEquals(null, insnList.getFirst());
+ assertEquals(null, insnList.getLast());
+ assertFalse(insnList.contains(insn));
+ assertArrayEquals(new AbstractInsnNode[0], insnList.toArray());
+ assertEquals(null, insn.getPrevious());
+ assertEquals(null, insn.getNext());
+ }
+
+ @Test
+ void testResetLabels() {
+ InsnList insnList = newInsnList();
+ LabelNode labelNode = new LabelNode();
+ insnList.add(new InsnNode(55));
+ insnList.add(labelNode);
+ insnList.add(new InsnNode(77));
+ Label label = labelNode.getLabel();
+
+ insnList.resetLabels();
+
+ assertNotNull(label);
+ assertNotSame(label, labelNode.getLabel());
+ }
+
+ private static InsnList newInsnList() {
+ return new CheckedInsnList();
+ }
+
+ private static InsnList newInsnList(final InsnNode insnNode1, final InsnNode insnNode2) {
+ InsnList insnList = new CheckedInsnList();
+ insnList.add(insnNode1);
+ insnList.add(insnNode2);
+ return insnList;
+ }
+
+ /** An {@link InsnList} which checks that its methods are properly used. */
+ static class CheckedInsnList extends InsnList {
+
+ @Override
+ public int indexOf(final AbstractInsnNode insnNode) {
+ if (!contains(insnNode)) {
+ throw new NoSuchElementException();
+ }
+ return super.indexOf(insnNode);
+ }
+
+ @Override
+ public void set(final AbstractInsnNode oldInsnNode, final AbstractInsnNode newInsnNode) {
+ if (!contains(oldInsnNode)) {
+ throw new NoSuchElementException();
+ }
+ if (newInsnNode.index != -1) {
+ throw new IllegalArgumentException();
+ }
+ super.set(oldInsnNode, newInsnNode);
+ }
+
+ @Override
+ public void add(final AbstractInsnNode insnNode) {
+ if (insnNode.index != -1) {
+ throw new IllegalArgumentException();
+ }
+ super.add(insnNode);
+ }
+
+ @Override
+ public void add(final InsnList insnList) {
+ if (insnList == this) {
+ throw new IllegalArgumentException();
+ }
+ super.add(insnList);
+ }
+
+ @Override
+ public void insert(final AbstractInsnNode insnNode) {
+ if (insnNode.index != -1) {
+ throw new IllegalArgumentException();
+ }
+ super.insert(insnNode);
+ }
+
+ @Override
+ public void insert(final InsnList insnList) {
+ if (insnList == this) {
+ throw new IllegalArgumentException();
+ }
+ super.insert(insnList);
+ }
+
+ @Override
+ public void insert(final AbstractInsnNode previousInsn, final AbstractInsnNode insnNode) {
+ if (!contains(previousInsn)) {
+ throw new NoSuchElementException();
+ }
+ if (insnNode.index != -1) {
+ throw new IllegalArgumentException();
+ }
+ super.insert(previousInsn, insnNode);
+ }
+
+ @Override
+ public void insert(final AbstractInsnNode previousInsn, final InsnList insnList) {
+ if (!contains(previousInsn)) {
+ throw new NoSuchElementException();
+ }
+ if (insnList == this) {
+ throw new IllegalArgumentException();
+ }
+ super.insert(previousInsn, insnList);
+ }
+
+ @Override
+ public void insertBefore(final AbstractInsnNode nextInsn, final AbstractInsnNode insnNode) {
+ if (!contains(nextInsn)) {
+ throw new NoSuchElementException();
+ }
+ if (insnNode.index != -1) {
+ throw new IllegalArgumentException();
+ }
+ super.insertBefore(nextInsn, insnNode);
+ }
+
+ @Override
+ public void insertBefore(final AbstractInsnNode nextInsn, final InsnList insnList) {
+ if (!contains(nextInsn)) {
+ throw new NoSuchElementException();
+ }
+ if (insnList == this) {
+ throw new IllegalArgumentException();
+ }
+ super.insertBefore(nextInsn, insnList);
+ }
+
+ @Override
+ public void remove(final AbstractInsnNode insnNode) {
+ if (!contains(insnNode)) {
+ throw new NoSuchElementException();
+ }
+ super.remove(insnNode);
+ }
+
+ @Override
+ public void clear() {
+ removeAll(true);
+ super.clear();
+ }
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnNodeTest.java
new file mode 100644
index 00000000..53c99b90
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnNodeTest.java
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link InsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class InsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ InsnNode insnNode = new InsnNode(Opcodes.ACONST_NULL);
+
+ assertEquals(AbstractInsnNode.INSN, insnNode.getType());
+ assertEquals(Opcodes.ACONST_NULL, insnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/IntInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/IntInsnNodeTest.java
new file mode 100644
index 00000000..7081d7f8
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/IntInsnNodeTest.java
@@ -0,0 +1,59 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link IntInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class IntInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ IntInsnNode intInsnNode = new IntInsnNode(Opcodes.BIPUSH, 0);
+
+ assertEquals(Opcodes.BIPUSH, intInsnNode.getOpcode());
+ assertEquals(AbstractInsnNode.INT_INSN, intInsnNode.getType());
+ }
+
+ @Test
+ void testSetOpcode() {
+ IntInsnNode intInsnNode = new IntInsnNode(Opcodes.BIPUSH, 0);
+
+ intInsnNode.setOpcode(Opcodes.SIPUSH);
+
+ assertEquals(Opcodes.SIPUSH, intInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/InvokeDynamicInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/InvokeDynamicInsnNodeTest.java
new file mode 100644
index 00000000..6b1ef10b
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/InvokeDynamicInsnNodeTest.java
@@ -0,0 +1,59 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link InvokeDynamicInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class InvokeDynamicInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ Handle handle = new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "()V", false);
+ Object[] bootstrapMethodArguments = new Object[] {"s"};
+
+ InvokeDynamicInsnNode invokeDynamicInsnNode =
+ new InvokeDynamicInsnNode("name", "()V", handle, bootstrapMethodArguments);
+
+ assertEquals(Opcodes.INVOKEDYNAMIC, invokeDynamicInsnNode.getOpcode());
+ assertEquals(AbstractInsnNode.INVOKE_DYNAMIC_INSN, invokeDynamicInsnNode.getType());
+ assertEquals("name", invokeDynamicInsnNode.name);
+ assertEquals("()V", invokeDynamicInsnNode.desc);
+ assertEquals(handle, invokeDynamicInsnNode.bsm);
+ assertEquals(bootstrapMethodArguments, invokeDynamicInsnNode.bsmArgs);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/JumpInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/JumpInsnNodeTest.java
new file mode 100644
index 00000000..de67d9d4
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/JumpInsnNodeTest.java
@@ -0,0 +1,62 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link JumpInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class JumpInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ LabelNode labelNode = new LabelNode();
+
+ JumpInsnNode jumpInsnNode = new JumpInsnNode(Opcodes.GOTO, labelNode);
+
+ assertEquals(Opcodes.GOTO, jumpInsnNode.getOpcode());
+ assertEquals(AbstractInsnNode.JUMP_INSN, jumpInsnNode.getType());
+ assertEquals(labelNode, jumpInsnNode.label);
+ }
+
+ @Test
+ void testSetOpcode() {
+ JumpInsnNode jumpInsnNode = new JumpInsnNode(Opcodes.GOTO, new LabelNode());
+
+ jumpInsnNode.setOpcode(Opcodes.IFEQ);
+
+ assertEquals(Opcodes.IFEQ, jumpInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/LabelNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/LabelNodeTest.java
new file mode 100644
index 00000000..d7a84a33
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/LabelNodeTest.java
@@ -0,0 +1,55 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link LabelNode}.
+ *
+ * @author Eric Bruneton
+ */
+class LabelNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ Label label = new Label();
+
+ LabelNode labelNode1 = new LabelNode();
+ LabelNode labelNode2 = new LabelNode(label);
+
+ assertEquals(AbstractInsnNode.LABEL, labelNode1.getType());
+ assertNotNull(labelNode1.getLabel());
+ assertEquals(label, labelNode2.getLabel());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/LdcInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/LdcInsnNodeTest.java
new file mode 100644
index 00000000..1198c318
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/LdcInsnNodeTest.java
@@ -0,0 +1,49 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link LdcInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class LdcInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ LdcInsnNode ldcInsnNode = new LdcInsnNode("s");
+
+ assertEquals(AbstractInsnNode.LDC_INSN, ldcInsnNode.getType());
+ assertEquals("s", ldcInsnNode.cst);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/LineNumberNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/LineNumberNodeTest.java
new file mode 100644
index 00000000..44ed650e
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/LineNumberNodeTest.java
@@ -0,0 +1,52 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link LineNumberNode}.
+ *
+ * @author Eric Bruneton
+ */
+class LineNumberNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ LabelNode labelNode = new LabelNode();
+
+ LineNumberNode lineNumberNode = new LineNumberNode(42, labelNode);
+
+ assertEquals(42, lineNumberNode.line);
+ assertEquals(labelNode, lineNumberNode.start);
+ assertEquals(AbstractInsnNode.LINE, lineNumberNode.getType());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/LookupSwitchInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/LookupSwitchInsnNodeTest.java
new file mode 100644
index 00000000..4313ea56
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/LookupSwitchInsnNodeTest.java
@@ -0,0 +1,56 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link LookupSwitchInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class LookupSwitchInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ LabelNode dflt = new LabelNode();
+ int[] keys = new int[] {1};
+ LabelNode[] labels = new LabelNode[] {new LabelNode()};
+
+ LookupSwitchInsnNode lookupSwitchInsnNode = new LookupSwitchInsnNode(dflt, keys, labels);
+
+ assertEquals(AbstractInsnNode.LOOKUPSWITCH_INSN, lookupSwitchInsnNode.getType());
+ assertEquals(dflt, lookupSwitchInsnNode.dflt);
+ assertEquals(Arrays.asList(new Integer[] {1}), lookupSwitchInsnNode.keys);
+ assertEquals(Arrays.asList(labels), lookupSwitchInsnNode.labels);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/MethodInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/MethodInsnNodeTest.java
new file mode 100644
index 00000000..27f27abb
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/MethodInsnNodeTest.java
@@ -0,0 +1,83 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link MethodInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class MethodInsnNodeTest extends AsmTest {
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedConstructor() {
+ MethodInsnNode methodInsnNode1 =
+ new MethodInsnNode(Opcodes.INVOKESTATIC, "owner", "name", "()I");
+ MethodInsnNode methodInsnNode2 =
+ new MethodInsnNode(Opcodes.INVOKEINTERFACE, "owner", "name", "()I");
+
+ assertEquals(AbstractInsnNode.METHOD_INSN, methodInsnNode1.getType());
+ assertEquals(AbstractInsnNode.METHOD_INSN, methodInsnNode2.getType());
+ assertEquals(Opcodes.INVOKESTATIC, methodInsnNode1.getOpcode());
+ assertEquals(Opcodes.INVOKEINTERFACE, methodInsnNode2.getOpcode());
+ assertFalse(methodInsnNode1.itf);
+ assertTrue(methodInsnNode2.itf);
+ }
+
+ @Test
+ void testConstrutor() {
+ MethodInsnNode methodInsnNode =
+ new MethodInsnNode(Opcodes.INVOKESTATIC, "owner", "name", "()I", false);
+
+ assertEquals(AbstractInsnNode.METHOD_INSN, methodInsnNode.getType());
+ assertEquals(Opcodes.INVOKESTATIC, methodInsnNode.getOpcode());
+ assertEquals("owner", methodInsnNode.owner);
+ assertEquals("name", methodInsnNode.name);
+ assertEquals("()I", methodInsnNode.desc);
+ assertFalse(methodInsnNode.itf);
+ }
+
+ @Test
+ void testSetOpcode() {
+ MethodInsnNode methodInsnNode =
+ new MethodInsnNode(Opcodes.INVOKESTATIC, "owner", "name", "()I", false);
+
+ methodInsnNode.setOpcode(Opcodes.INVOKESPECIAL);
+
+ assertEquals(Opcodes.INVOKESPECIAL, methodInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/MethodNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/MethodNodeTest.java
new file mode 100644
index 00000000..d59e5875
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/MethodNodeTest.java
@@ -0,0 +1,120 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link MethodNode}.
+ *
+ * @author Eric Bruneton
+ */
+class MethodNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ MethodNode methodNode = new MethodNode(123, "method", "()V", null, null);
+
+ assertEquals(123, methodNode.access);
+ assertEquals("method", methodNode.name);
+ assertEquals("()V", methodNode.desc);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new MethodNode() {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+
+ /** Tests that an uninitialized MethodNode can receive any visit method call. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitAndAccept_withUninitializedMethodNode(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassNode classNode =
+ new ClassNode(apiParameter.value()) {
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodNode method = new MethodNode();
+ method.access = access;
+ method.name = name;
+ method.desc = descriptor;
+ method.signature = signature;
+ method.exceptions = exceptions == null ? null : Arrays.asList(exceptions);
+ methods.add(method);
+ return method;
+ }
+ };
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classNode, new Attribute[] {new Comment(), new CodeComment()}, 0);
+ classNode.accept(classWriter);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ @Test
+ void testClone() {
+ MethodNode methodNode = new MethodNode();
+ methodNode.visitCode();
+ methodNode.visitLabel(new Label());
+ methodNode.visitInsn(Opcodes.NOP);
+ methodNode.visitLabel(new Label());
+ methodNode.visitEnd();
+
+ MethodNode cloneMethodNode = new MethodNode();
+ methodNode.accept(cloneMethodNode);
+ methodNode.accept(cloneMethodNode);
+
+ assertEquals(6, cloneMethodNode.instructions.size());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java
new file mode 100644
index 00000000..799e8306
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java
@@ -0,0 +1,99 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link ModuleNode}.
+ *
+ * @author Eric Bruneton
+ */
+class ModuleNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ ModuleNode moduleNode1 = new ModuleNode("module1", 123, "1.0");
+ ModuleNode moduleNode2 =
+ new ModuleNode(
+ /* latest */ Opcodes.ASM10_EXPERIMENTAL,
+ "module2",
+ 456,
+ "2.0",
+ null,
+ null,
+ null,
+ null,
+ null) {};
+
+ assertEquals("module1", moduleNode1.name);
+ assertEquals(123, moduleNode1.access);
+ assertEquals("1.0", moduleNode1.version);
+ assertEquals("module2", moduleNode2.name);
+ assertEquals(456, moduleNode2.access);
+ assertEquals("2.0", moduleNode2.version);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new ModuleNode("module", 123, "1.0") {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+
+ @Test
+ void testAccept() {
+ ModuleNode moduleNode = new ModuleNode("module", 123, "1.0");
+ ModuleNode dstModuleNode = new ModuleNode("", 0, "");
+ ClassVisitor copyModuleVisitor =
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+ @Override
+ public ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ dstModuleNode.name = name;
+ dstModuleNode.access = access;
+ dstModuleNode.version = version;
+ return dstModuleNode;
+ }
+ };
+
+ moduleNode.accept(copyModuleVisitor);
+
+ assertEquals("module", dstModuleNode.name);
+ assertEquals(123, dstModuleNode.access);
+ assertEquals("1.0", dstModuleNode.version);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/MultiANewArrayInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/MultiANewArrayInsnNodeTest.java
new file mode 100644
index 00000000..17fba1eb
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/MultiANewArrayInsnNodeTest.java
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link MultiANewArrayInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class MultiANewArrayInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ MultiANewArrayInsnNode multiANewArrayInsnNode = new MultiANewArrayInsnNode("[[I", 2);
+
+ assertEquals(AbstractInsnNode.MULTIANEWARRAY_INSN, multiANewArrayInsnNode.getType());
+ assertEquals("[[I", multiANewArrayInsnNode.desc);
+ assertEquals(2, multiANewArrayInsnNode.dims);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/RecordComponentNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/RecordComponentNodeTest.java
new file mode 100644
index 00000000..0954a8b1
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/RecordComponentNodeTest.java
@@ -0,0 +1,58 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link RecordComponentNode}.
+ *
+ * @author Eric Bruneton
+ */
+class RecordComponentNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ RecordComponentNode componentNode = new RecordComponentNode("component", "I", null);
+
+ assertEquals("component", componentNode.name);
+ assertEquals("I", componentNode.descriptor);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ Executable constructor = () -> new RecordComponentNode("component", "I", null) {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/TableSwitchInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/TableSwitchInsnNodeTest.java
new file mode 100644
index 00000000..54e659de
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/TableSwitchInsnNodeTest.java
@@ -0,0 +1,56 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link TableSwitchInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class TableSwitchInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ LabelNode dflt = new LabelNode();
+ LabelNode[] labels = new LabelNode[] {new LabelNode()};
+
+ TableSwitchInsnNode tableSwitchInsnNode = new TableSwitchInsnNode(0, 1, dflt, labels);
+
+ assertEquals(AbstractInsnNode.TABLESWITCH_INSN, tableSwitchInsnNode.getType());
+ assertEquals(0, tableSwitchInsnNode.min);
+ assertEquals(1, tableSwitchInsnNode.max);
+ assertEquals(dflt, tableSwitchInsnNode.dflt);
+ assertEquals(Arrays.asList(labels), tableSwitchInsnNode.labels);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/TypeAnnotationNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/TypeAnnotationNodeTest.java
new file mode 100644
index 00000000..710e9aa0
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/TypeAnnotationNodeTest.java
@@ -0,0 +1,64 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link TypeAnnotationNode}.
+ *
+ * @author Eric Bruneton
+ */
+class TypeAnnotationNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ TypePath typePath = TypePath.fromString("[");
+
+ TypeAnnotationNode typeAnnotationNode = new TypeAnnotationNode(123, typePath, "LI;");
+
+ assertEquals(123, typeAnnotationNode.typeRef);
+ assertEquals(typePath, typeAnnotationNode.typePath);
+ assertEquals("LI;", typeAnnotationNode.desc);
+ }
+
+ @Test
+ void testConstructor_illegalState() {
+ TypePath typePath = TypePath.fromString("[");
+
+ Executable constructor = () -> new TypeAnnotationNode(123, typePath, "LI;") {};
+
+ assertThrows(IllegalStateException.class, constructor);
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/TypeInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/TypeInsnNodeTest.java
new file mode 100644
index 00000000..f613ed2a
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/TypeInsnNodeTest.java
@@ -0,0 +1,60 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link TypeInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class TypeInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ TypeInsnNode typeInsnNode = new TypeInsnNode(Opcodes.NEW, "java/lang/Object");
+
+ assertEquals(Opcodes.NEW, typeInsnNode.getOpcode());
+ assertEquals(AbstractInsnNode.TYPE_INSN, typeInsnNode.getType());
+ assertEquals("java/lang/Object", typeInsnNode.desc);
+ }
+
+ @Test
+ void testSetOpcode() {
+ TypeInsnNode typeInsnNode = new TypeInsnNode(Opcodes.NEW, "java/lang/Object");
+
+ typeInsnNode.setOpcode(Opcodes.CHECKCAST);
+
+ assertEquals(Opcodes.CHECKCAST, typeInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/UtilTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/UtilTest.java
new file mode 100644
index 00000000..8fcf4371
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/UtilTest.java
@@ -0,0 +1,76 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link Util}.
+ *
+ * @author Eric Bruneton
+ */
+class UtilTest {
+
+ @Test
+ void testAsArrayList_nullArray() {
+ assertTrue(Util.asArrayList((Object[]) null).isEmpty());
+ assertTrue(Util.asArrayList((byte[]) null).isEmpty());
+ assertTrue(Util.asArrayList((boolean[]) null).isEmpty());
+ assertTrue(Util.asArrayList((short[]) null).isEmpty());
+ assertTrue(Util.asArrayList((char[]) null).isEmpty());
+ assertTrue(Util.asArrayList((int[]) null).isEmpty());
+ assertTrue(Util.asArrayList((float[]) null).isEmpty());
+ assertTrue(Util.asArrayList((long[]) null).isEmpty());
+ assertTrue(Util.asArrayList((double[]) null).isEmpty());
+ }
+
+ @Test
+ void testAsArrayList_withLength() {
+ List<String> strings = Util.asArrayList(3);
+
+ assertEquals(3, strings.size());
+ assertNull(strings.get(0));
+ assertNull(strings.get(1));
+ assertNull(strings.get(2));
+ }
+
+ @Test
+ void testAsArrayList_withLengthAndArray() {
+ List<Integer> ints = Util.asArrayList(3, new Integer[] {1, 2, 3, 4, 5});
+
+ assertEquals(3, ints.size());
+ assertEquals(Integer.valueOf(1), ints.get(0));
+ assertEquals(Integer.valueOf(2), ints.get(1));
+ assertEquals(Integer.valueOf(3), ints.get(2));
+ }
+}
diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/VarInsnNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/VarInsnNodeTest.java
new file mode 100644
index 00000000..f3c22721
--- /dev/null
+++ b/asm-tree/src/test/java/org/objectweb/asm/tree/VarInsnNodeTest.java
@@ -0,0 +1,60 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tree;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link VarInsnNode}.
+ *
+ * @author Eric Bruneton
+ */
+class VarInsnNodeTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ VarInsnNode varInsnNode = new VarInsnNode(Opcodes.ALOAD, 123);
+
+ assertEquals(Opcodes.ALOAD, varInsnNode.getOpcode());
+ assertEquals(AbstractInsnNode.VAR_INSN, varInsnNode.getType());
+ assertEquals(123, varInsnNode.var);
+ }
+
+ @Test
+ void testSetOpcode() {
+ VarInsnNode varInsnNode = new VarInsnNode(Opcodes.ALOAD, 123);
+
+ varInsnNode.setOpcode(Opcodes.ASTORE);
+
+ assertEquals(Opcodes.ASTORE, varInsnNode.getOpcode());
+ }
+}
diff --git a/asm-tree/src/test/resources/sigtest-4.0.txt b/asm-tree/src/test/resources/sigtest-4.0.txt
new file mode 100644
index 00000000..ba35c621
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-4.0.txt
@@ -0,0 +1,442 @@
+#Signature file v4.1
+#Version 4.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,next,prev
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List attrs
+fld public java.util.List fields
+fld public java.util.List innerClasses
+fld public java.util.List interfaces
+fld public java.util.List invisibleAnnotations
+fld public java.util.List methods
+fld public java.util.List visibleAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List invisibleAnnotations
+fld public java.util.List visibleAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List local
+fld public java.util.List stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator iterator()
+meth public java.util.ListIterator iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,first,last,size
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds label
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List keys
+fld public java.util.List labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List localVariables
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-5.0.txt b/asm-tree/src/test/resources/sigtest-5.0.txt
new file mode 100644
index 00000000..7968f880
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-5.0.txt
@@ -0,0 +1,503 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,next,prev
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds class$org$objectweb$asm$tree$AnnotationNode
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List attrs
+fld public java.util.List fields
+fld public java.util.List innerClasses
+fld public java.util.List interfaces
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List methods
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds class$org$objectweb$asm$tree$ClassNode
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds class$org$objectweb$asm$tree$FieldNode
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List local
+fld public java.util.List stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator iterator()
+meth public java.util.ListIterator iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,first,last,size
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds label
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List end
+fld public java.util.List index
+fld public java.util.List start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List keys
+fld public java.util.List labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List attrs
+fld public java.util.List exceptions
+fld public java.util.List invisibleAnnotations
+fld public java.util.List invisibleLocalVariableAnnotations
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List localVariables
+fld public java.util.List parameters
+fld public java.util.List tryCatchBlocks
+fld public java.util.List visibleAnnotations
+fld public java.util.List visibleLocalVariableAnnotations
+fld public java.util.List visibleTypeAnnotations
+fld public java.util.List[] invisibleParameterAnnotations
+fld public java.util.List[] visibleParameterAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds class$org$objectweb$asm$tree$MethodNode,visited
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List invisibleTypeAnnotations
+fld public java.util.List visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+hfds class$org$objectweb$asm$tree$TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-6.0.txt b/asm-tree/src/test/resources/sigtest-6.0.txt
new file mode 100644
index 00000000..9bb1a1d4
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-6.0.txt
@@ -0,0 +1,576 @@
+#Signature file v4.1
+#Version 6.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,next,prev
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,first,last,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds label
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int maxLocals
+fld public int maxStack
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-6.1.txt b/asm-tree/src/test/resources/sigtest-6.1.txt
new file mode 100644
index 00000000..55f319c8
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-6.1.txt
@@ -0,0 +1,627 @@
+#Signature file v4.1
+#Version 6.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-7.0.txt b/asm-tree/src/test/resources/sigtest-7.0.txt
new file mode 100644
index 00000000..b5208dd2
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-7.0.txt
@@ -0,0 +1,633 @@
+#Signature file v4.1
+#Version 7.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-7.1.txt b/asm-tree/src/test/resources/sigtest-7.1.txt
new file mode 100644
index 00000000..80478658
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-7.1.txt
@@ -0,0 +1,632 @@
+#Signature file v4.1
+#Version 7.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-7.2.txt b/asm-tree/src/test/resources/sigtest-7.2.txt
new file mode 100644
index 00000000..d77eb7eb
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-7.2.txt
@@ -0,0 +1,638 @@
+#Signature file v4.1
+#Version 7.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-7.3.1.txt b/asm-tree/src/test/resources/sigtest-7.3.1.txt
new file mode 100644
index 00000000..e4545f04
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-7.3.1.txt
@@ -0,0 +1,659 @@
+#Signature file v4.1
+#Version 7.3.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-8.0.1.txt b/asm-tree/src/test/resources/sigtest-8.0.1.txt
new file mode 100644
index 00000000..6f1c8dd5
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-8.0.1.txt
@@ -0,0 +1,672 @@
+#Signature file v4.1
+#Version 8.0.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.RecordComponentNode> recordComponents
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String descriptor
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-9.0.txt b/asm-tree/src/test/resources/sigtest-9.0.txt
new file mode 100644
index 00000000..5b992e60
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-9.0.txt
@@ -0,0 +1,675 @@
+#Signature file v4.1
+#Version 9.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<java.lang.String> permittedSubclasses
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.RecordComponentNode> recordComponents
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String descriptor
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-9.1.txt b/asm-tree/src/test/resources/sigtest-9.1.txt
new file mode 100644
index 00000000..2e9739a9
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-9.1.txt
@@ -0,0 +1,675 @@
+#Signature file v4.1
+#Version 9.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<java.lang.String> permittedSubclasses
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.RecordComponentNode> recordComponents
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String descriptor
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-9.2.txt b/asm-tree/src/test/resources/sigtest-9.2.txt
new file mode 100644
index 00000000..e93da27a
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-9.2.txt
@@ -0,0 +1,675 @@
+#Signature file v4.1
+#Version 9.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<java.lang.String> permittedSubclasses
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.RecordComponentNode> recordComponents
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String descriptor
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-tree/src/test/resources/sigtest-9.4.txt b/asm-tree/src/test/resources/sigtest-9.4.txt
new file mode 100644
index 00000000..4b8a39df
--- /dev/null
+++ b/asm-tree/src/test/resources/sigtest-9.4.txt
@@ -0,0 +1,680 @@
+#Signature file v4.1
+#Version 9.4
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor getDelegate()
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.ClassVisitor getDelegate()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.MethodVisitor getDelegate()
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor getDelegate()
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.RecordComponentVisitor delegate
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.tree.AbstractInsnNode
+cons protected init(int)
+fld protected int opcode
+fld public final static int FIELD_INSN = 4
+fld public final static int FRAME = 14
+fld public final static int IINC_INSN = 10
+fld public final static int INSN = 0
+fld public final static int INT_INSN = 1
+fld public final static int INVOKE_DYNAMIC_INSN = 6
+fld public final static int JUMP_INSN = 7
+fld public final static int LABEL = 8
+fld public final static int LDC_INSN = 9
+fld public final static int LINE = 15
+fld public final static int LOOKUPSWITCH_INSN = 12
+fld public final static int METHOD_INSN = 5
+fld public final static int MULTIANEWARRAY_INSN = 13
+fld public final static int TABLESWITCH_INSN = 11
+fld public final static int TYPE_INSN = 3
+fld public final static int VAR_INSN = 2
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth protected final org.objectweb.asm.tree.AbstractInsnNode cloneAnnotations(org.objectweb.asm.tree.AbstractInsnNode)
+meth protected final void acceptAnnotations(org.objectweb.asm.MethodVisitor)
+meth public abstract int getType()
+meth public abstract org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public abstract void accept(org.objectweb.asm.MethodVisitor)
+meth public int getOpcode()
+meth public org.objectweb.asm.tree.AbstractInsnNode getNext()
+meth public org.objectweb.asm.tree.AbstractInsnNode getPrevious()
+supr java.lang.Object
+hfds index,nextInsn,previousInsn
+
+CLSS public org.objectweb.asm.tree.AnnotationNode
+cons public init(int,java.lang.String)
+cons public init(java.lang.String)
+fld public java.lang.String desc
+fld public java.util.List<java.lang.Object> values
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void accept(org.objectweb.asm.AnnotationVisitor)
+meth public void check(int)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+
+CLSS public org.objectweb.asm.tree.ClassNode
+cons public init()
+cons public init(int)
+fld public int access
+fld public int version
+fld public java.lang.String name
+fld public java.lang.String nestHostClass
+fld public java.lang.String outerClass
+fld public java.lang.String outerMethod
+fld public java.lang.String outerMethodDesc
+fld public java.lang.String signature
+fld public java.lang.String sourceDebug
+fld public java.lang.String sourceFile
+fld public java.lang.String superName
+fld public java.util.List<java.lang.String> interfaces
+fld public java.util.List<java.lang.String> nestMembers
+fld public java.util.List<java.lang.String> permittedSubclasses
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.FieldNode> fields
+fld public java.util.List<org.objectweb.asm.tree.InnerClassNode> innerClasses
+fld public java.util.List<org.objectweb.asm.tree.MethodNode> methods
+fld public java.util.List<org.objectweb.asm.tree.RecordComponentNode> recordComponents
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.ModuleNode module
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+
+CLSS public org.objectweb.asm.tree.FieldInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.FieldNode
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+fld public int access
+fld public java.lang.Object value
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public org.objectweb.asm.tree.FrameNode
+cons public init(int,int,java.lang.Object[],int,java.lang.Object[])
+fld public int type
+fld public java.util.List<java.lang.Object> local
+fld public java.util.List<java.lang.Object> stack
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IincInsnNode
+cons public init(int,int)
+fld public int incr
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InnerClassNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+fld public int access
+fld public java.lang.String innerName
+fld public java.lang.String name
+fld public java.lang.String outerName
+meth public void accept(org.objectweb.asm.ClassVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.InsnList
+cons public init()
+intf java.lang.Iterable<org.objectweb.asm.tree.AbstractInsnNode>
+meth public boolean contains(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int indexOf(org.objectweb.asm.tree.AbstractInsnNode)
+meth public int size()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator()
+meth public java.util.ListIterator<org.objectweb.asm.tree.AbstractInsnNode> iterator(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode get(int)
+meth public org.objectweb.asm.tree.AbstractInsnNode getFirst()
+meth public org.objectweb.asm.tree.AbstractInsnNode getLast()
+meth public org.objectweb.asm.tree.AbstractInsnNode[] toArray()
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void add(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void add(org.objectweb.asm.tree.InsnList)
+meth public void clear()
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insert(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void insert(org.objectweb.asm.tree.InsnList)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+meth public void insertBefore(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.InsnList)
+meth public void remove(org.objectweb.asm.tree.AbstractInsnNode)
+meth public void resetLabels()
+meth public void set(org.objectweb.asm.tree.AbstractInsnNode,org.objectweb.asm.tree.AbstractInsnNode)
+supr java.lang.Object
+hfds cache,firstInsn,lastInsn,size
+hcls InsnListIterator
+
+CLSS public org.objectweb.asm.tree.InsnNode
+cons public init(int)
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.IntInsnNode
+cons public init(int,int)
+fld public int operand
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.InvokeDynamicInsnNode
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+fld public java.lang.Object[] bsmArgs
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public org.objectweb.asm.Handle bsm
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.JumpInsnNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public org.objectweb.asm.tree.LabelNode label
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LabelNode
+cons public init()
+cons public init(org.objectweb.asm.Label)
+meth public int getType()
+meth public org.objectweb.asm.Label getLabel()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void resetLabel()
+supr org.objectweb.asm.tree.AbstractInsnNode
+hfds value
+
+CLSS public org.objectweb.asm.tree.LdcInsnNode
+cons public init(java.lang.Object)
+fld public java.lang.Object cst
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LineNumberNode
+cons public init(int,org.objectweb.asm.tree.LabelNode)
+fld public int line
+fld public org.objectweb.asm.tree.LabelNode start
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,org.objectweb.asm.tree.LabelNode[],org.objectweb.asm.tree.LabelNode[],int[],java.lang.String)
+fld public java.util.List<java.lang.Integer> index
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> end
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> start
+meth public void accept(org.objectweb.asm.MethodVisitor,boolean)
+supr org.objectweb.asm.tree.TypeAnnotationNode
+
+CLSS public org.objectweb.asm.tree.LocalVariableNode
+cons public init(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,int)
+fld public int index
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.LookupSwitchInsnNode
+cons public init(org.objectweb.asm.tree.LabelNode,int[],org.objectweb.asm.tree.LabelNode[])
+fld public java.util.List<java.lang.Integer> keys
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodInsnNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+fld public boolean itf
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String owner
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.MethodNode
+cons public init()
+cons public init(int)
+cons public init(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+fld public int access
+fld public int invisibleAnnotableParameterCount
+fld public int maxLocals
+fld public int maxStack
+fld public int visibleAnnotableParameterCount
+fld public java.lang.Object annotationDefault
+fld public java.lang.String desc
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<java.lang.String> exceptions
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] invisibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode>[] visibleParameterAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> invisibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableAnnotationNode> visibleLocalVariableAnnotations
+fld public java.util.List<org.objectweb.asm.tree.LocalVariableNode> localVariables
+fld public java.util.List<org.objectweb.asm.tree.ParameterNode> parameters
+fld public java.util.List<org.objectweb.asm.tree.TryCatchBlockNode> tryCatchBlocks
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.InsnList instructions
+meth protected org.objectweb.asm.tree.LabelNode getLabelNode(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void check(int)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds visited
+
+CLSS public org.objectweb.asm.tree.ModuleExportNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleNode
+cons public init(int,java.lang.String,int,java.lang.String,java.util.List<org.objectweb.asm.tree.ModuleRequireNode>,java.util.List<org.objectweb.asm.tree.ModuleExportNode>,java.util.List<org.objectweb.asm.tree.ModuleOpenNode>,java.util.List<java.lang.String>,java.util.List<org.objectweb.asm.tree.ModuleProvideNode>)
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String mainClass
+fld public java.lang.String name
+fld public java.lang.String version
+fld public java.util.List<java.lang.String> packages
+fld public java.util.List<java.lang.String> uses
+fld public java.util.List<org.objectweb.asm.tree.ModuleExportNode> exports
+fld public java.util.List<org.objectweb.asm.tree.ModuleOpenNode> opens
+fld public java.util.List<org.objectweb.asm.tree.ModuleProvideNode> provides
+fld public java.util.List<org.objectweb.asm.tree.ModuleRequireNode> requires
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public org.objectweb.asm.tree.ModuleOpenNode
+cons public init(java.lang.String,int,java.util.List<java.lang.String>)
+fld public int access
+fld public java.lang.String packaze
+fld public java.util.List<java.lang.String> modules
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleProvideNode
+cons public init(java.lang.String,java.util.List<java.lang.String>)
+fld public java.lang.String service
+fld public java.util.List<java.lang.String> providers
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.ModuleRequireNode
+cons public init(java.lang.String,int,java.lang.String)
+fld public int access
+fld public java.lang.String module
+fld public java.lang.String version
+meth public void accept(org.objectweb.asm.ModuleVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.MultiANewArrayInsnNode
+cons public init(java.lang.String,int)
+fld public int dims
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.ParameterNode
+cons public init(java.lang.String,int)
+fld public int access
+fld public java.lang.String name
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.RecordComponentNode
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(java.lang.String,java.lang.String,java.lang.String)
+fld public java.lang.String descriptor
+fld public java.lang.String name
+fld public java.lang.String signature
+fld public java.util.List<org.objectweb.asm.Attribute> attrs
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> invisibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.AnnotationNode> visibleAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void accept(org.objectweb.asm.ClassVisitor)
+meth public void check(int)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public org.objectweb.asm.tree.TableSwitchInsnNode
+cons public !varargs init(int,int,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode[])
+fld public int max
+fld public int min
+fld public java.util.List<org.objectweb.asm.tree.LabelNode> labels
+fld public org.objectweb.asm.tree.LabelNode dflt
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.TryCatchBlockNode
+cons public init(org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode,java.lang.String)
+fld public java.lang.String type
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> invisibleTypeAnnotations
+fld public java.util.List<org.objectweb.asm.tree.TypeAnnotationNode> visibleTypeAnnotations
+fld public org.objectweb.asm.tree.LabelNode end
+fld public org.objectweb.asm.tree.LabelNode handler
+fld public org.objectweb.asm.tree.LabelNode start
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void updateIndex(int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.tree.TypeAnnotationNode
+cons public init(int,int,org.objectweb.asm.TypePath,java.lang.String)
+cons public init(int,org.objectweb.asm.TypePath,java.lang.String)
+fld public int typeRef
+fld public org.objectweb.asm.TypePath typePath
+supr org.objectweb.asm.tree.AnnotationNode
+
+CLSS public org.objectweb.asm.tree.TypeInsnNode
+cons public init(int,java.lang.String)
+fld public java.lang.String desc
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
+CLSS public org.objectweb.asm.tree.UnsupportedClassVersionException
+cons public init()
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public org.objectweb.asm.tree.VarInsnNode
+cons public init(int,int)
+fld public int var
+meth public int getType()
+meth public org.objectweb.asm.tree.AbstractInsnNode clone(java.util.Map<org.objectweb.asm.tree.LabelNode,org.objectweb.asm.tree.LabelNode>)
+meth public void accept(org.objectweb.asm.MethodVisitor)
+meth public void setOpcode(int)
+supr org.objectweb.asm.tree.AbstractInsnNode
+
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java
new file mode 100644
index 00000000..28f960c0
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java
@@ -0,0 +1,1612 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link Printer} that prints the ASM code to generate the classes it visits.
+ *
+ * @author Eric Bruneton
+ */
+// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+public class ASMifier extends Printer {
+
+ /** The help message shown when command line arguments are incorrect. */
+ private static final String USAGE =
+ "Prints the ASM code to generate the given class.\n"
+ + "Usage: ASMifier [-nodebug] <fully qualified class name or class file name>";
+
+ /** A pseudo access flag used to distinguish class access flags. */
+ private static final int ACCESS_CLASS = 0x40000;
+
+ /** A pseudo access flag used to distinguish field access flags. */
+ private static final int ACCESS_FIELD = 0x80000;
+
+ /** A pseudo access flag used to distinguish inner class flags. */
+ private static final int ACCESS_INNER = 0x100000;
+
+ /** A pseudo access flag used to distinguish module requires / exports flags. */
+ private static final int ACCESS_MODULE = 0x200000;
+
+ private static final String ANNOTATION_VISITOR = "annotationVisitor";
+ private static final String ANNOTATION_VISITOR0 = "annotationVisitor0 = ";
+ private static final String COMMA = "\", \"";
+ private static final String END_ARRAY = " });\n";
+ private static final String END_PARAMETERS = ");\n\n";
+ private static final String NEW_OBJECT_ARRAY = ", new Object[] {";
+ private static final String VISIT_END = ".visitEnd();\n";
+
+ private static final List<String> FRAME_TYPES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ "Opcodes.TOP",
+ "Opcodes.INTEGER",
+ "Opcodes.FLOAT",
+ "Opcodes.DOUBLE",
+ "Opcodes.LONG",
+ "Opcodes.NULL",
+ "Opcodes.UNINITIALIZED_THIS"));
+
+ private static final Map<Integer, String> CLASS_VERSIONS;
+
+ static {
+ HashMap<Integer, String> classVersions = new HashMap<>();
+ classVersions.put(Opcodes.V1_1, "V1_1");
+ classVersions.put(Opcodes.V1_2, "V1_2");
+ classVersions.put(Opcodes.V1_3, "V1_3");
+ classVersions.put(Opcodes.V1_4, "V1_4");
+ classVersions.put(Opcodes.V1_5, "V1_5");
+ classVersions.put(Opcodes.V1_6, "V1_6");
+ classVersions.put(Opcodes.V1_7, "V1_7");
+ classVersions.put(Opcodes.V1_8, "V1_8");
+ classVersions.put(Opcodes.V9, "V9");
+ classVersions.put(Opcodes.V10, "V10");
+ classVersions.put(Opcodes.V11, "V11");
+ classVersions.put(Opcodes.V12, "V12");
+ classVersions.put(Opcodes.V13, "V13");
+ classVersions.put(Opcodes.V14, "V14");
+ classVersions.put(Opcodes.V15, "V15");
+ classVersions.put(Opcodes.V16, "V16");
+ classVersions.put(Opcodes.V17, "V17");
+ classVersions.put(Opcodes.V18, "V18");
+ classVersions.put(Opcodes.V19, "V19");
+ classVersions.put(Opcodes.V20, "V20");
+ CLASS_VERSIONS = Collections.unmodifiableMap(classVersions);
+ }
+
+ /** The name of the visitor variable in the produced code. */
+ protected final String name;
+
+ /** The identifier of the annotation visitor variable in the produced code. */
+ protected final int id;
+
+ /** The name of the Label variables in the produced code. */
+ protected Map<Label, String> labelNames;
+
+ /**
+ * Constructs a new {@link ASMifier}. <i>Subclasses must not use this constructor</i>. Instead,
+ * they must use the {@link #ASMifier(int, String, int)} version.
+ *
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public ASMifier() {
+ this(/* latest api = */ Opcodes.ASM9, "classWriter", 0);
+ if (getClass() != ASMifier.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link ASMifier}.
+ *
+ * @param api the ASM API version implemented by this class. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param visitorVariableName the name of the visitor variable in the produced code.
+ * @param annotationVisitorId identifier of the annotation visitor variable in the produced code.
+ */
+ protected ASMifier(
+ final int api, final String visitorVariableName, final int annotationVisitorId) {
+ super(api);
+ this.name = visitorVariableName;
+ this.id = annotationVisitorId;
+ }
+
+ /**
+ * Prints the ASM source code to generate the given class to the standard output.
+ *
+ * <p>Usage: ASMifier [-nodebug] &lt;binary class name or class file name&gt;
+ *
+ * @param args the command line arguments.
+ * @throws IOException if the class cannot be found, or if an IOException occurs.
+ */
+ public static void main(final String[] args) throws IOException {
+ main(args, new PrintWriter(System.out, true), new PrintWriter(System.err, true));
+ }
+
+ /**
+ * Prints the ASM source code to generate the given class to the given output.
+ *
+ * <p>Usage: ASMifier [-nodebug] &lt;binary class name or class file name&gt;
+ *
+ * @param args the command line arguments.
+ * @param output where to print the result.
+ * @param logger where to log errors.
+ * @throws IOException if the class cannot be found, or if an IOException occurs.
+ */
+ static void main(final String[] args, final PrintWriter output, final PrintWriter logger)
+ throws IOException {
+ main(args, USAGE, new ASMifier(), output, logger);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Classes
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ String simpleName;
+ if (name == null) {
+ simpleName = "module-info";
+ } else {
+ int lastSlashIndex = name.lastIndexOf('/');
+ if (lastSlashIndex == -1) {
+ simpleName = name;
+ } else {
+ text.add("package asm." + name.substring(0, lastSlashIndex).replace('/', '.') + ";\n");
+ simpleName = name.substring(lastSlashIndex + 1).replaceAll("[-\\(\\)]", "_");
+ }
+ }
+ text.add("import org.objectweb.asm.AnnotationVisitor;\n");
+ text.add("import org.objectweb.asm.Attribute;\n");
+ text.add("import org.objectweb.asm.ClassReader;\n");
+ text.add("import org.objectweb.asm.ClassWriter;\n");
+ text.add("import org.objectweb.asm.ConstantDynamic;\n");
+ text.add("import org.objectweb.asm.FieldVisitor;\n");
+ text.add("import org.objectweb.asm.Handle;\n");
+ text.add("import org.objectweb.asm.Label;\n");
+ text.add("import org.objectweb.asm.MethodVisitor;\n");
+ text.add("import org.objectweb.asm.Opcodes;\n");
+ text.add("import org.objectweb.asm.RecordComponentVisitor;\n");
+ text.add("import org.objectweb.asm.Type;\n");
+ text.add("import org.objectweb.asm.TypePath;\n");
+ text.add("public class " + simpleName + "Dump implements Opcodes {\n\n");
+ text.add("public static byte[] dump () throws Exception {\n\n");
+ text.add("ClassWriter classWriter = new ClassWriter(0);\n");
+ text.add("FieldVisitor fieldVisitor;\n");
+ text.add("RecordComponentVisitor recordComponentVisitor;\n");
+ text.add("MethodVisitor methodVisitor;\n");
+ text.add("AnnotationVisitor annotationVisitor0;\n\n");
+
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visit(");
+ String versionString = CLASS_VERSIONS.get(version);
+ if (versionString != null) {
+ stringBuilder.append(versionString);
+ } else {
+ stringBuilder.append(version);
+ }
+ stringBuilder.append(", ");
+ appendAccessFlags(access | ACCESS_CLASS);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(signature);
+ stringBuilder.append(", ");
+ appendConstant(superName);
+ stringBuilder.append(", ");
+ if (interfaces != null && interfaces.length > 0) {
+ stringBuilder.append("new String[] {");
+ for (int i = 0; i < interfaces.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendConstant(interfaces[i]);
+ }
+ stringBuilder.append(" }");
+ } else {
+ stringBuilder.append("null");
+ }
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitSource(final String file, final String debug) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitSource(");
+ appendConstant(file);
+ stringBuilder.append(", ");
+ appendConstant(debug);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitModule(final String name, final int flags, final String version) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("{\n");
+ stringBuilder.append("ModuleVisitor moduleVisitor = classWriter.visitModule(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendAccessFlags(flags | ACCESS_MODULE);
+ stringBuilder.append(", ");
+ appendConstant(version);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier("moduleVisitor", 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitNestHost(");
+ appendConstant(nestHost);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitOuterClass(");
+ appendConstant(owner);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public ASMifier visitClassAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public ASMifier visitClassTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitClassAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitNestMember(");
+ appendConstant(nestMember);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitPermittedSubclass(");
+ appendConstant(permittedSubclass);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("classWriter.visitInnerClass(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(outerName);
+ stringBuilder.append(", ");
+ appendConstant(innerName);
+ stringBuilder.append(", ");
+ appendAccessFlags(access | ACCESS_INNER);
+ stringBuilder.append(END_PARAMETERS);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public ASMifier visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("{\n");
+ stringBuilder.append("recordComponentVisitor = classWriter.visitRecordComponent(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(signature);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier("recordComponentVisitor", 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public ASMifier visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("{\n");
+ stringBuilder.append("fieldVisitor = classWriter.visitField(");
+ appendAccessFlags(access | ACCESS_FIELD);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(signature);
+ stringBuilder.append(", ");
+ appendConstant(value);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier("fieldVisitor", 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public ASMifier visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("{\n");
+ stringBuilder.append("methodVisitor = classWriter.visitMethod(");
+ appendAccessFlags(access);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(signature);
+ stringBuilder.append(", ");
+ if (exceptions != null && exceptions.length > 0) {
+ stringBuilder.append("new String[] {");
+ for (int i = 0; i < exceptions.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendConstant(exceptions[i]);
+ }
+ stringBuilder.append(" }");
+ } else {
+ stringBuilder.append("null");
+ }
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier("methodVisitor", 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public void visitClassEnd() {
+ text.add("classWriter.visitEnd();\n\n");
+ text.add("return classWriter.toByteArray();\n");
+ text.add("}\n");
+ text.add("}\n");
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Modules
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("moduleVisitor.visitMainClass(");
+ appendConstant(mainClass);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("moduleVisitor.visitPackage(");
+ appendConstant(packaze);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("moduleVisitor.visitRequire(");
+ appendConstant(module);
+ stringBuilder.append(", ");
+ appendAccessFlags(access | ACCESS_MODULE);
+ stringBuilder.append(", ");
+ appendConstant(version);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ visitExportOrOpen("moduleVisitor.visitExport(", packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ visitExportOrOpen("moduleVisitor.visitOpen(", packaze, access, modules);
+ }
+
+ private void visitExportOrOpen(
+ final String visitMethod, final String packaze, final int access, final String... modules) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(visitMethod);
+ appendConstant(packaze);
+ stringBuilder.append(", ");
+ appendAccessFlags(access | ACCESS_MODULE);
+ if (modules != null && modules.length > 0) {
+ stringBuilder.append(", new String[] {");
+ for (int i = 0; i < modules.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendConstant(modules[i]);
+ }
+ stringBuilder.append(" }");
+ }
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitUse(final String service) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("moduleVisitor.visitUse(");
+ appendConstant(service);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("moduleVisitor.visitProvide(");
+ appendConstant(service);
+ stringBuilder.append(", new String[] {");
+ for (int i = 0; i < providers.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendConstant(providers[i]);
+ }
+ stringBuilder.append(END_ARRAY);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ text.add("moduleVisitor.visitEnd();\n");
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Annotations
+ // -----------------------------------------------------------------------------------------------
+
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ @Override
+ public void visit(final String name, final Object value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(ANNOTATION_VISITOR).append(id).append(".visit(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(value);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(ANNOTATION_VISITOR).append(id).append(".visitEnum(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(value);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public ASMifier visitAnnotation(final String name, final String descriptor) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append("AnnotationVisitor annotationVisitor")
+ .append(id + 1)
+ .append(" = annotationVisitor");
+ stringBuilder.append(id).append(".visitAnnotation(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, id + 1);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public ASMifier visitArray(final String name) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("{\n");
+ stringBuilder
+ .append("AnnotationVisitor annotationVisitor")
+ .append(id + 1)
+ .append(" = annotationVisitor");
+ stringBuilder.append(id).append(".visitArray(");
+ appendConstant(name);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, id + 1);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public void visitAnnotationEnd() {
+ stringBuilder.setLength(0);
+ stringBuilder.append(ANNOTATION_VISITOR).append(id).append(VISIT_END);
+ text.add(stringBuilder.toString());
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Record components
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public ASMifier visitRecordComponentAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public ASMifier visitRecordComponentTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitRecordComponentAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitRecordComponentEnd() {
+ visitMemberEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Fields
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public ASMifier visitFieldAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public ASMifier visitFieldTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitFieldAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitFieldEnd() {
+ visitMemberEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitParameter(final String parameterName, final int access) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitParameter(");
+ appendString(stringBuilder, parameterName);
+ stringBuilder.append(", ");
+ appendAccessFlags(access);
+ text.add(stringBuilder.append(");\n").toString());
+ }
+
+ @Override
+ public ASMifier visitAnnotationDefault() {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append(ANNOTATION_VISITOR0)
+ .append(name)
+ .append(".visitAnnotationDefault();\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public ASMifier visitMethodAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public ASMifier visitMethodTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public ASMifier visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(name)
+ .append(".visitAnnotableParameterCount(")
+ .append(parameterCount)
+ .append(", ")
+ .append(visible)
+ .append(");\n");
+ text.add(stringBuilder.toString());
+ return this;
+ }
+
+ @Override
+ public ASMifier visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append(ANNOTATION_VISITOR0)
+ .append(name)
+ .append(".visitParameterAnnotation(")
+ .append(parameter)
+ .append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ").append(visible).append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public void visitMethodAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitCode() {
+ text.add(name + ".visitCode();\n");
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ stringBuilder.setLength(0);
+ switch (type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ declareFrameTypes(numLocal, local);
+ declareFrameTypes(numStack, stack);
+ if (type == Opcodes.F_NEW) {
+ stringBuilder.append(name).append(".visitFrame(Opcodes.F_NEW, ");
+ } else {
+ stringBuilder.append(name).append(".visitFrame(Opcodes.F_FULL, ");
+ }
+ stringBuilder.append(numLocal).append(NEW_OBJECT_ARRAY);
+ appendFrameTypes(numLocal, local);
+ stringBuilder.append("}, ").append(numStack).append(NEW_OBJECT_ARRAY);
+ appendFrameTypes(numStack, stack);
+ stringBuilder.append('}');
+ break;
+ case Opcodes.F_APPEND:
+ declareFrameTypes(numLocal, local);
+ stringBuilder
+ .append(name)
+ .append(".visitFrame(Opcodes.F_APPEND,")
+ .append(numLocal)
+ .append(NEW_OBJECT_ARRAY);
+ appendFrameTypes(numLocal, local);
+ stringBuilder.append("}, 0, null");
+ break;
+ case Opcodes.F_CHOP:
+ stringBuilder
+ .append(name)
+ .append(".visitFrame(Opcodes.F_CHOP,")
+ .append(numLocal)
+ .append(", null, 0, null");
+ break;
+ case Opcodes.F_SAME:
+ stringBuilder.append(name).append(".visitFrame(Opcodes.F_SAME, 0, null, 0, null");
+ break;
+ case Opcodes.F_SAME1:
+ declareFrameTypes(1, stack);
+ stringBuilder
+ .append(name)
+ .append(".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {");
+ appendFrameTypes(1, stack);
+ stringBuilder.append('}');
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitInsn(").append(OPCODES[opcode]).append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(name)
+ .append(".visitIntInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer.toString(operand))
+ .append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(name)
+ .append(".visitVarInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(varIndex)
+ .append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitTypeInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(type);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(this.name).append(".visitFieldInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(owner);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(this.name)
+ .append(".visitMethodInsn(")
+ .append(OPCODES[opcode])
+ .append(", ");
+ appendConstant(owner);
+ stringBuilder.append(", ");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ stringBuilder.append(isInterface ? "true" : "false");
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(this.name).append(".visitInvokeDynamicInsn(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(bootstrapMethodHandle);
+ stringBuilder.append(", new Object[]{");
+ for (int i = 0; i < bootstrapMethodArguments.length; ++i) {
+ appendConstant(bootstrapMethodArguments[i]);
+ if (i != bootstrapMethodArguments.length - 1) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("});\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ stringBuilder.setLength(0);
+ declareLabel(label);
+ stringBuilder.append(name).append(".visitJumpInsn(").append(OPCODES[opcode]).append(", ");
+ appendLabel(label);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ stringBuilder.setLength(0);
+ declareLabel(label);
+ stringBuilder.append(name).append(".visitLabel(");
+ appendLabel(label);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitLdcInsn(");
+ appendConstant(value);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(name)
+ .append(".visitIincInsn(")
+ .append(varIndex)
+ .append(", ")
+ .append(increment)
+ .append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ stringBuilder.setLength(0);
+ for (Label label : labels) {
+ declareLabel(label);
+ }
+ declareLabel(dflt);
+
+ stringBuilder
+ .append(name)
+ .append(".visitTableSwitchInsn(")
+ .append(min)
+ .append(", ")
+ .append(max)
+ .append(", ");
+ appendLabel(dflt);
+ stringBuilder.append(", new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ stringBuilder.append(END_ARRAY);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ stringBuilder.setLength(0);
+ for (Label label : labels) {
+ declareLabel(label);
+ }
+ declareLabel(dflt);
+
+ stringBuilder.append(name).append(".visitLookupSwitchInsn(");
+ appendLabel(dflt);
+ stringBuilder.append(", new int[] {");
+ for (int i = 0; i < keys.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ").append(keys[i]);
+ }
+ stringBuilder.append(" }, new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ stringBuilder.append(END_ARRAY);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitMultiANewArrayInsn(");
+ appendConstant(descriptor);
+ stringBuilder.append(", ").append(numDimensions).append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public ASMifier visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation("visitInsnAnnotation", typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ stringBuilder.setLength(0);
+ declareLabel(start);
+ declareLabel(end);
+ declareLabel(handler);
+ stringBuilder.append(name).append(".visitTryCatchBlock(");
+ appendLabel(start);
+ stringBuilder.append(", ");
+ appendLabel(end);
+ stringBuilder.append(", ");
+ appendLabel(handler);
+ stringBuilder.append(", ");
+ appendConstant(type);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public ASMifier visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation("visitTryCatchAnnotation", typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(this.name).append(".visitLocalVariable(");
+ appendConstant(name);
+ stringBuilder.append(", ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ");
+ appendConstant(signature);
+ stringBuilder.append(", ");
+ appendLabel(start);
+ stringBuilder.append(", ");
+ appendLabel(end);
+ stringBuilder.append(", ").append(index).append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append(ANNOTATION_VISITOR0)
+ .append(name)
+ .append(".visitLocalVariableAnnotation(")
+ .append(typeRef);
+ if (typePath == null) {
+ stringBuilder.append(", null, ");
+ } else {
+ stringBuilder.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
+ }
+ stringBuilder.append("new Label[] {");
+ for (int i = 0; i < start.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendLabel(start[i]);
+ }
+ stringBuilder.append(" }, new Label[] {");
+ for (int i = 0; i < end.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ");
+ appendLabel(end[i]);
+ }
+ stringBuilder.append(" }, new int[] {");
+ for (int i = 0; i < index.length; ++i) {
+ stringBuilder.append(i == 0 ? " " : ", ").append(index[i]);
+ }
+ stringBuilder.append(" }, ");
+ appendConstant(descriptor);
+ stringBuilder.append(", ").append(visible).append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(".visitLineNumber(").append(line).append(", ");
+ appendLabel(start);
+ stringBuilder.append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(name)
+ .append(".visitMaxs(")
+ .append(maxStack)
+ .append(", ")
+ .append(maxLocals)
+ .append(");\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMethodEnd() {
+ visitMemberEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Common methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits a class, field or method annotation.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a new {@link ASMifier} to visit the annotation values.
+ */
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ public ASMifier visitAnnotation(final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append(ANNOTATION_VISITOR0)
+ .append(name)
+ .append(".visitAnnotation(");
+ appendConstant(descriptor);
+ stringBuilder.append(", ").append(visible).append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ /**
+ * Visits a class, field or method type annotation.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link org.objectweb.asm.TypeReference#FIELD}. See {@link org.objectweb.asm.TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a new {@link ASMifier} to visit the annotation values.
+ */
+ public ASMifier visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation("visitTypeAnnotation", typeRef, typePath, descriptor, visible);
+ }
+
+ /**
+ * Visits a class, field, method, instruction or try catch block type annotation.
+ *
+ * @param method the name of the visit method for this type of annotation.
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link org.objectweb.asm.TypeReference#FIELD}. See {@link org.objectweb.asm.TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a new {@link ASMifier} to visit the annotation values.
+ */
+ public ASMifier visitTypeAnnotation(
+ final String method,
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("{\n")
+ .append(ANNOTATION_VISITOR0)
+ .append(name)
+ .append('.')
+ .append(method)
+ .append('(')
+ .append(typeRef);
+ if (typePath == null) {
+ stringBuilder.append(", null, ");
+ } else {
+ stringBuilder.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
+ }
+ appendConstant(descriptor);
+ stringBuilder.append(", ").append(visible).append(");\n");
+ text.add(stringBuilder.toString());
+ ASMifier asmifier = createASMifier(ANNOTATION_VISITOR, 0);
+ text.add(asmifier.getText());
+ text.add("}\n");
+ return asmifier;
+ }
+
+ /**
+ * Visit a class, field or method attribute.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ stringBuilder.setLength(0);
+ stringBuilder.append("// ATTRIBUTE ").append(attribute.type).append('\n');
+ if (attribute instanceof ASMifierSupport) {
+ if (labelNames == null) {
+ labelNames = new HashMap<>();
+ }
+ stringBuilder.append("{\n");
+ ((ASMifierSupport) attribute).asmify(stringBuilder, "attribute", labelNames);
+ stringBuilder.append(name).append(".visitAttribute(attribute);\n");
+ stringBuilder.append("}\n");
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ /** Visits the end of a field, record component or method. */
+ private void visitMemberEnd() {
+ stringBuilder.setLength(0);
+ stringBuilder.append(name).append(VISIT_END);
+ text.add(stringBuilder.toString());
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link ASMifier}.
+ *
+ * @param visitorVariableName the name of the visitor variable in the produced code.
+ * @param annotationVisitorId identifier of the annotation visitor variable in the produced code.
+ * @return a new {@link ASMifier}.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ protected ASMifier createASMifier(
+ final String visitorVariableName, final int annotationVisitorId) {
+ return new ASMifier(api, visitorVariableName, annotationVisitorId);
+ }
+
+ /**
+ * Appends a string representation of the given access flags to {@link #stringBuilder}.
+ *
+ * @param accessFlags some access flags.
+ */
+ private void appendAccessFlags(final int accessFlags) {
+ boolean isEmpty = true;
+ if ((accessFlags & Opcodes.ACC_PUBLIC) != 0) {
+ stringBuilder.append("ACC_PUBLIC");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_PRIVATE) != 0) {
+ stringBuilder.append("ACC_PRIVATE");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_PROTECTED) != 0) {
+ stringBuilder.append("ACC_PROTECTED");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_FINAL) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_FINAL");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_STATIC) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_STATIC");
+ isEmpty = false;
+ }
+ if ((accessFlags & (Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSITIVE))
+ != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ if ((accessFlags & ACCESS_CLASS) == 0) {
+ if ((accessFlags & ACCESS_MODULE) == 0) {
+ stringBuilder.append("ACC_SYNCHRONIZED");
+ } else {
+ stringBuilder.append("ACC_TRANSITIVE");
+ }
+ } else {
+ stringBuilder.append("ACC_SUPER");
+ }
+ isEmpty = false;
+ }
+ if ((accessFlags & (Opcodes.ACC_VOLATILE | Opcodes.ACC_BRIDGE | Opcodes.ACC_STATIC_PHASE))
+ != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ if ((accessFlags & ACCESS_FIELD) == 0) {
+ if ((accessFlags & ACCESS_MODULE) == 0) {
+ stringBuilder.append("ACC_BRIDGE");
+ } else {
+ stringBuilder.append("ACC_STATIC_PHASE");
+ }
+ } else {
+ stringBuilder.append("ACC_VOLATILE");
+ }
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_VARARGS) != 0
+ && (accessFlags & (ACCESS_CLASS | ACCESS_FIELD)) == 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_VARARGS");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_TRANSIENT) != 0 && (accessFlags & ACCESS_FIELD) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_TRANSIENT");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_NATIVE) != 0
+ && (accessFlags & (ACCESS_CLASS | ACCESS_FIELD)) == 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_NATIVE");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_ENUM) != 0
+ && (accessFlags & (ACCESS_CLASS | ACCESS_FIELD | ACCESS_INNER)) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_ENUM");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_ANNOTATION) != 0
+ && (accessFlags & (ACCESS_CLASS | ACCESS_INNER)) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_ANNOTATION");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_ABSTRACT) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_ABSTRACT");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_INTERFACE) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_INTERFACE");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_STRICT) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_STRICT");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_SYNTHETIC");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_DEPRECATED");
+ isEmpty = false;
+ }
+ if ((accessFlags & Opcodes.ACC_RECORD) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ stringBuilder.append("ACC_RECORD");
+ isEmpty = false;
+ }
+ if ((accessFlags & (Opcodes.ACC_MANDATED | Opcodes.ACC_MODULE)) != 0) {
+ if (!isEmpty) {
+ stringBuilder.append(" | ");
+ }
+ if ((accessFlags & ACCESS_CLASS) == 0) {
+ stringBuilder.append("ACC_MANDATED");
+ } else {
+ stringBuilder.append("ACC_MODULE");
+ }
+ isEmpty = false;
+ }
+ if (isEmpty) {
+ stringBuilder.append('0');
+ }
+ }
+
+ /**
+ * Appends a string representation of the given constant to {@link #stringBuilder}.
+ *
+ * @param value a {@link String}, {@link Type}, {@link Handle}, {@link Byte}, {@link Short},
+ * {@link Character}, {@link Integer}, {@link Float}, {@link Long} or {@link Double} object,
+ * or an array of primitive values. May be {@literal null}.
+ */
+ protected void appendConstant(final Object value) {
+ if (value == null) {
+ stringBuilder.append("null");
+ } else if (value instanceof String) {
+ appendString(stringBuilder, (String) value);
+ } else if (value instanceof Type) {
+ stringBuilder.append("Type.getType(\"");
+ stringBuilder.append(((Type) value).getDescriptor());
+ stringBuilder.append("\")");
+ } else if (value instanceof Handle) {
+ stringBuilder.append("new Handle(");
+ Handle handle = (Handle) value;
+ stringBuilder.append("Opcodes.").append(HANDLE_TAG[handle.getTag()]).append(", \"");
+ stringBuilder.append(handle.getOwner()).append(COMMA);
+ stringBuilder.append(handle.getName()).append(COMMA);
+ stringBuilder.append(handle.getDesc()).append("\", ");
+ stringBuilder.append(handle.isInterface()).append(')');
+ } else if (value instanceof ConstantDynamic) {
+ stringBuilder.append("new ConstantDynamic(\"");
+ ConstantDynamic constantDynamic = (ConstantDynamic) value;
+ stringBuilder.append(constantDynamic.getName()).append(COMMA);
+ stringBuilder.append(constantDynamic.getDescriptor()).append("\", ");
+ appendConstant(constantDynamic.getBootstrapMethod());
+ stringBuilder.append(NEW_OBJECT_ARRAY);
+ int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
+ for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
+ appendConstant(constantDynamic.getBootstrapMethodArgument(i));
+ if (i != bootstrapMethodArgumentCount - 1) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("})");
+ } else if (value instanceof Byte) {
+ stringBuilder.append("new Byte((byte)").append(value).append(')');
+ } else if (value instanceof Boolean) {
+ stringBuilder.append(((Boolean) value).booleanValue() ? "Boolean.TRUE" : "Boolean.FALSE");
+ } else if (value instanceof Short) {
+ stringBuilder.append("new Short((short)").append(value).append(')');
+ } else if (value instanceof Character) {
+ stringBuilder
+ .append("new Character((char)")
+ .append((int) ((Character) value).charValue())
+ .append(')');
+ } else if (value instanceof Integer) {
+ stringBuilder.append("new Integer(").append(value).append(')');
+ } else if (value instanceof Float) {
+ stringBuilder.append("new Float(\"").append(value).append("\")");
+ } else if (value instanceof Long) {
+ stringBuilder.append("new Long(").append(value).append("L)");
+ } else if (value instanceof Double) {
+ stringBuilder.append("new Double(\"").append(value).append("\")");
+ } else if (value instanceof byte[]) {
+ byte[] byteArray = (byte[]) value;
+ stringBuilder.append("new byte[] {");
+ for (int i = 0; i < byteArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(byteArray[i]);
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof boolean[]) {
+ boolean[] booleanArray = (boolean[]) value;
+ stringBuilder.append("new boolean[] {");
+ for (int i = 0; i < booleanArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(booleanArray[i]);
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof short[]) {
+ short[] shortArray = (short[]) value;
+ stringBuilder.append("new short[] {");
+ for (int i = 0; i < shortArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append("(short)").append(shortArray[i]);
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof char[]) {
+ char[] charArray = (char[]) value;
+ stringBuilder.append("new char[] {");
+ for (int i = 0; i < charArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append("(char)").append((int) charArray[i]);
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof int[]) {
+ int[] intArray = (int[]) value;
+ stringBuilder.append("new int[] {");
+ for (int i = 0; i < intArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(intArray[i]);
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof long[]) {
+ long[] longArray = (long[]) value;
+ stringBuilder.append("new long[] {");
+ for (int i = 0; i < longArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(longArray[i]).append('L');
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof float[]) {
+ float[] floatArray = (float[]) value;
+ stringBuilder.append("new float[] {");
+ for (int i = 0; i < floatArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(floatArray[i]).append('f');
+ }
+ stringBuilder.append('}');
+ } else if (value instanceof double[]) {
+ double[] doubleArray = (double[]) value;
+ stringBuilder.append("new double[] {");
+ for (int i = 0; i < doubleArray.length; i++) {
+ stringBuilder.append(i == 0 ? "" : ",").append(doubleArray[i]).append('d');
+ }
+ stringBuilder.append('}');
+ }
+ }
+
+ /**
+ * Calls {@link #declareLabel} for each label in the given stack map frame types.
+ *
+ * @param numTypes the number of stack map frame types in 'frameTypes'.
+ * @param frameTypes an array of stack map frame types, in the format described in {@link
+ * org.objectweb.asm.MethodVisitor#visitFrame}.
+ */
+ private void declareFrameTypes(final int numTypes, final Object[] frameTypes) {
+ for (int i = 0; i < numTypes; ++i) {
+ if (frameTypes[i] instanceof Label) {
+ declareLabel((Label) frameTypes[i]);
+ }
+ }
+ }
+
+ /**
+ * Appends the given stack map frame types to {@link #stringBuilder}.
+ *
+ * @param numTypes the number of stack map frame types in 'frameTypes'.
+ * @param frameTypes an array of stack map frame types, in the format described in {@link
+ * org.objectweb.asm.MethodVisitor#visitFrame}.
+ */
+ private void appendFrameTypes(final int numTypes, final Object[] frameTypes) {
+ for (int i = 0; i < numTypes; ++i) {
+ if (i > 0) {
+ stringBuilder.append(", ");
+ }
+ if (frameTypes[i] instanceof String) {
+ appendConstant(frameTypes[i]);
+ } else if (frameTypes[i] instanceof Integer) {
+ stringBuilder.append(FRAME_TYPES.get(((Integer) frameTypes[i]).intValue()));
+ } else {
+ appendLabel((Label) frameTypes[i]);
+ }
+ }
+ }
+
+ /**
+ * Appends a declaration of the given label to {@link #stringBuilder}. This declaration is of the
+ * form "Label labelXXX = new Label();". Does nothing if the given label has already been
+ * declared.
+ *
+ * @param label a label.
+ */
+ protected void declareLabel(final Label label) {
+ if (labelNames == null) {
+ labelNames = new HashMap<>();
+ }
+ String labelName = labelNames.get(label);
+ if (labelName == null) {
+ labelName = "label" + labelNames.size();
+ labelNames.put(label, labelName);
+ stringBuilder.append("Label ").append(labelName).append(" = new Label();\n");
+ }
+ }
+
+ /**
+ * Appends the name of the given label to {@link #stringBuilder}. The given label <i>must</i>
+ * already have a name. One way to ensure this is to always call {@link #declareLabel} before
+ * calling this method.
+ *
+ * @param label a label.
+ */
+ protected void appendLabel(final Label label) {
+ stringBuilder.append(labelNames.get(label));
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/ASMifierSupport.java b/asm-util/src/main/java/org/objectweb/asm/util/ASMifierSupport.java
new file mode 100644
index 00000000..b7c525cd
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/ASMifierSupport.java
@@ -0,0 +1,45 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
+ * France Telecom All rights reserved.
+ *
+ * <p>Redistribution and use in source and binary forms, with or without modification, are permitted
+ * provided that the following conditions are met: 1. Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific prior written permission.
+ *
+ * <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.util.Map;
+import org.objectweb.asm.Label;
+
+/**
+ * An {@link org.objectweb.asm.Attribute} that can generate the ASM code to create an equivalent
+ * attribute.
+ *
+ * @author Eugene Kuleshov
+ */
+// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+public interface ASMifierSupport {
+
+ /**
+ * Generates the ASM code to create an attribute equal to this attribute.
+ *
+ * @param outputBuilder where the generated code must be appended.
+ * @param visitorVariableName the name of the visitor variable in the produced code.
+ * @param labelNames the names of the labels in the generated code.
+ */
+ void asmify(
+ StringBuilder outputBuilder, String visitorVariableName, Map<Label, String> labelNames);
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java
new file mode 100644
index 00000000..499c0aee
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java
@@ -0,0 +1,135 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * An {@link AnnotationVisitor} that checks that its methods are properly used.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckAnnotationAdapter extends AnnotationVisitor {
+
+ /**
+ * Whether the values of the visited annotation are named. AnnotationVisitor instances used for
+ * annotation default and annotation arrays use unnamed values.
+ */
+ private final boolean useNamedValue;
+
+ /** Whether the {@link #visitEnd} method has been called. */
+ private boolean visitEndCalled;
+
+ public CheckAnnotationAdapter(final AnnotationVisitor annotationVisitor) {
+ this(annotationVisitor, true);
+ }
+
+ CheckAnnotationAdapter(final AnnotationVisitor annotationVisitor, final boolean useNamedValues) {
+ super(/* latest api = */ Opcodes.ASM9, annotationVisitor);
+ this.useNamedValue = useNamedValues;
+ }
+
+ @Override
+ public void visit(final String name, final Object value) {
+ checkVisitEndNotCalled();
+ checkName(name);
+ if (!(value instanceof Byte
+ || value instanceof Boolean
+ || value instanceof Character
+ || value instanceof Short
+ || value instanceof Integer
+ || value instanceof Long
+ || value instanceof Float
+ || value instanceof Double
+ || value instanceof String
+ || value instanceof Type
+ || value instanceof byte[]
+ || value instanceof boolean[]
+ || value instanceof char[]
+ || value instanceof short[]
+ || value instanceof int[]
+ || value instanceof long[]
+ || value instanceof float[]
+ || value instanceof double[])) {
+ throw new IllegalArgumentException("Invalid annotation value");
+ }
+ if (value instanceof Type && ((Type) value).getSort() == Type.METHOD) {
+ throw new IllegalArgumentException("Invalid annotation value");
+ }
+ super.visit(name, value);
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ checkVisitEndNotCalled();
+ checkName(name);
+ // Annotations can only appear in V1_5 or more classes.
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ if (value == null) {
+ throw new IllegalArgumentException("Invalid enum value");
+ }
+ super.visitEnum(name, descriptor, value);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ checkVisitEndNotCalled();
+ checkName(name);
+ // Annotations can only appear in V1_5 or more classes.
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ return new CheckAnnotationAdapter(super.visitAnnotation(name, descriptor));
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ checkVisitEndNotCalled();
+ checkName(name);
+ return new CheckAnnotationAdapter(super.visitArray(name), false);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkVisitEndNotCalled();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ private void checkName(final String name) {
+ if (useNamedValue && name == null) {
+ throw new IllegalArgumentException("Annotation value name must not be null");
+ }
+ }
+
+ private void checkVisitEndNotCalled() {
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java
new file mode 100644
index 00000000..4b12b240
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java
@@ -0,0 +1,1137 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.objectweb.asm.tree.analysis.BasicValue;
+import org.objectweb.asm.tree.analysis.Frame;
+import org.objectweb.asm.tree.analysis.SimpleVerifier;
+
+/**
+ * A {@link ClassVisitor} that checks that its methods are properly used. More precisely this class
+ * adapter checks each method call individually, based <i>only</i> on its arguments, but does
+ * <i>not</i> check the <i>sequence</i> of method calls. For example, the invalid sequence {@code
+ * visitField(ACC_PUBLIC, "i", "I", null)} {@code visitField(ACC_PUBLIC, "i", "D", null)} will
+ * <i>not</i> be detected by this class adapter.
+ *
+ * <p><code>CheckClassAdapter</code> can be also used to verify bytecode transformations in order to
+ * make sure that the transformed bytecode is sane. For example:
+ *
+ * <pre>
+ * InputStream inputStream = ...; // get bytes for the source class
+ * ClassReader classReader = new ClassReader(inputStream);
+ * ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
+ * ClassVisitor classVisitor = new <b>MyClassAdapter</b>(new CheckClassAdapter(classWriter, true));
+ * classReader.accept(classVisitor, 0);
+ *
+ * StringWriter stringWriter = new StringWriter();
+ * PrintWriter printWriter = new PrintWriter(stringWriter);
+ * CheckClassAdapter.verify(new ClassReader(classWriter.toByteArray()), false, printWriter);
+ * assertTrue(stringWriter.toString().isEmpty());
+ * </pre>
+ *
+ * <p>The above code pass the transformed bytecode through a <code>CheckClassAdapter</code>, with
+ * data flow checks enabled. These checks are not exactly the same as the JVM verification, but
+ * provide some basic type checking for each method instruction. If the bytecode has errors, the
+ * output text shows the erroneous instruction number, and a dump of the failed method with
+ * information about the type of the local variables and of the operand stack slots for each
+ * instruction. For example (format is - insnNumber locals : stack):
+ *
+ * <pre>
+ * org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
+ * at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:...)
+ * at org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:...)
+ * ...
+ * remove()V
+ * 00000 LinkedBlockingQueue$Itr . . . . . . . . : ICONST_0
+ * 00001 LinkedBlockingQueue$Itr . . . . . . . . : I ISTORE 2
+ * 00001 LinkedBlockingQueue$Itr <b>.</b> I . . . . . . :
+ * ...
+ * 00071 LinkedBlockingQueue$Itr <b>.</b> I . . . . . . : ILOAD 1
+ * 00072 <b>?</b> INVOKESPECIAL java/lang/Integer.&lt;init&gt; (I)V
+ * ...
+ * </pre>
+ *
+ * <p>The above output shows that the local variable 1, loaded by the <code>ILOAD 1</code>
+ * instruction at position <code>00071</code> is not initialized, whereas the local variable 2 is
+ * initialized and contains an int value.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckClassAdapter extends ClassVisitor {
+
+ /** The help message shown when command line arguments are incorrect. */
+ private static final String USAGE =
+ "Verifies the given class.\n"
+ + "Usage: CheckClassAdapter <fully qualified class name or class file name>";
+
+ private static final String ERROR_AT = ": error at index ";
+
+ /** Whether the bytecode must be checked with a BasicVerifier. */
+ private boolean checkDataFlow;
+
+ /** The class version number. */
+ private int version;
+
+ /** Whether the {@link #visit} method has been called. */
+ private boolean visitCalled;
+
+ /** Whether the {@link #visitModule} method has been called. */
+ private boolean visitModuleCalled;
+
+ /** Whether the {@link #visitSource} method has been called. */
+ private boolean visitSourceCalled;
+
+ /** Whether the {@link #visitOuterClass} method has been called. */
+ private boolean visitOuterClassCalled;
+
+ /** Whether the {@link #visitNestHost} method has been called. */
+ private boolean visitNestHostCalled;
+
+ /**
+ * The common package of all the nest members. Not {@literal null} if the visitNestMember method
+ * has been called.
+ */
+ private String nestMemberPackageName;
+
+ /** Whether the {@link #visitEnd} method has been called. */
+ private boolean visitEndCalled;
+
+ /** The index of the instruction designated by each visited label so far. */
+ private Map<Label, Integer> labelInsnIndices;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link CheckClassAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
+ *
+ * @param classVisitor the class visitor to which this adapter must delegate calls.
+ */
+ public CheckClassAdapter(final ClassVisitor classVisitor) {
+ this(classVisitor, /* checkDataFlow = */ true);
+ }
+
+ /**
+ * Constructs a new {@link CheckClassAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
+ *
+ * @param classVisitor the class visitor to which this adapter must delegate calls.
+ * @param checkDataFlow whether to perform basic data flow checks.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public CheckClassAdapter(final ClassVisitor classVisitor, final boolean checkDataFlow) {
+ this(/* latest api = */ Opcodes.ASM9, classVisitor, checkDataFlow);
+ if (getClass() != CheckClassAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckClassAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param classVisitor the class visitor to which this adapter must delegate calls.
+ * @param checkDataFlow {@literal true} to perform basic data flow checks, or {@literal false} to
+ * not perform any data flow check (see {@link CheckMethodAdapter}).
+ */
+ protected CheckClassAdapter(
+ final int api, final ClassVisitor classVisitor, final boolean checkDataFlow) {
+ super(api, classVisitor);
+ this.labelInsnIndices = new HashMap<>();
+ this.checkDataFlow = checkDataFlow;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if (visitCalled) {
+ throw new IllegalStateException("visit must be called only once");
+ }
+ visitCalled = true;
+ checkState();
+ checkAccess(
+ access,
+ Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_SUPER
+ | Opcodes.ACC_INTERFACE
+ | Opcodes.ACC_ABSTRACT
+ | Opcodes.ACC_SYNTHETIC
+ | Opcodes.ACC_ANNOTATION
+ | Opcodes.ACC_ENUM
+ | Opcodes.ACC_DEPRECATED
+ | Opcodes.ACC_RECORD
+ | Opcodes.ACC_MODULE);
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal class name (null)");
+ }
+ if (!name.endsWith("package-info") && !name.endsWith("module-info")) {
+ CheckMethodAdapter.checkInternalName(version, name, "class name");
+ }
+ if ("java/lang/Object".equals(name)) {
+ if (superName != null) {
+ throw new IllegalArgumentException(
+ "The super class name of the Object class must be 'null'");
+ }
+ } else if (name.endsWith("module-info")) {
+ if (superName != null) {
+ throw new IllegalArgumentException(
+ "The super class name of a module-info class must be 'null'");
+ }
+ } else {
+ CheckMethodAdapter.checkInternalName(version, superName, "super class name");
+ }
+ if (signature != null) {
+ checkClassSignature(signature);
+ }
+ if ((access & Opcodes.ACC_INTERFACE) != 0 && !"java/lang/Object".equals(superName)) {
+ throw new IllegalArgumentException(
+ "The super class name of interfaces must be 'java/lang/Object'");
+ }
+ if (interfaces != null) {
+ for (int i = 0; i < interfaces.length; ++i) {
+ CheckMethodAdapter.checkInternalName(
+ version, interfaces[i], "interface name at index " + i);
+ }
+ }
+ this.version = version;
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public void visitSource(final String file, final String debug) {
+ checkState();
+ if (visitSourceCalled) {
+ throw new IllegalStateException("visitSource can be called only once.");
+ }
+ visitSourceCalled = true;
+ super.visitSource(file, debug);
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ checkState();
+ if (visitModuleCalled) {
+ throw new IllegalStateException("visitModule can be called only once.");
+ }
+ visitModuleCalled = true;
+ checkFullyQualifiedName(this.version, name, "module name");
+ checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_MANDATED);
+ CheckModuleAdapter checkModuleAdapter =
+ new CheckModuleAdapter(
+ api, super.visitModule(name, access, version), (access & Opcodes.ACC_OPEN) != 0);
+ checkModuleAdapter.classVersion = this.version;
+ return checkModuleAdapter;
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ checkState();
+ CheckMethodAdapter.checkInternalName(version, nestHost, "nestHost");
+ if (visitNestHostCalled) {
+ throw new IllegalStateException("visitNestHost can be called only once.");
+ }
+ if (nestMemberPackageName != null) {
+ throw new IllegalStateException("visitNestHost and visitNestMember are mutually exclusive.");
+ }
+ visitNestHostCalled = true;
+ super.visitNestHost(nestHost);
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ checkState();
+ CheckMethodAdapter.checkInternalName(version, nestMember, "nestMember");
+ if (visitNestHostCalled) {
+ throw new IllegalStateException(
+ "visitMemberOfNest and visitNestHost are mutually exclusive.");
+ }
+ String packageName = packageName(nestMember);
+ if (nestMemberPackageName == null) {
+ nestMemberPackageName = packageName;
+ } else if (!nestMemberPackageName.equals(packageName)) {
+ throw new IllegalStateException(
+ "nest member " + nestMember + " should be in the package " + nestMemberPackageName);
+ }
+ super.visitNestMember(nestMember);
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ checkState();
+ CheckMethodAdapter.checkInternalName(version, permittedSubclass, "permittedSubclass");
+ super.visitPermittedSubclass(permittedSubclass);
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ checkState();
+ if (visitOuterClassCalled) {
+ throw new IllegalStateException("visitOuterClass can be called only once.");
+ }
+ visitOuterClassCalled = true;
+ if (owner == null) {
+ throw new IllegalArgumentException("Illegal outer class owner");
+ }
+ if (descriptor != null) {
+ CheckMethodAdapter.checkMethodDescriptor(version, descriptor);
+ }
+ super.visitOuterClass(owner, name, descriptor);
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ checkState();
+ CheckMethodAdapter.checkInternalName(version, name, "class name");
+ if (outerName != null) {
+ CheckMethodAdapter.checkInternalName(version, outerName, "outer class name");
+ }
+ if (innerName != null) {
+ int startIndex = 0;
+ while (startIndex < innerName.length() && Character.isDigit(innerName.charAt(startIndex))) {
+ startIndex++;
+ }
+ if (startIndex == 0 || startIndex < innerName.length()) {
+ CheckMethodAdapter.checkIdentifier(version, innerName, startIndex, -1, "inner class name");
+ }
+ }
+ checkAccess(
+ access,
+ Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_PRIVATE
+ | Opcodes.ACC_PROTECTED
+ | Opcodes.ACC_STATIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_INTERFACE
+ | Opcodes.ACC_ABSTRACT
+ | Opcodes.ACC_SYNTHETIC
+ | Opcodes.ACC_ANNOTATION
+ | Opcodes.ACC_ENUM);
+ super.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ checkState();
+ CheckMethodAdapter.checkUnqualifiedName(version, name, "record component name");
+ CheckMethodAdapter.checkDescriptor(version, descriptor, /* canBeVoid = */ false);
+ if (signature != null) {
+ checkFieldSignature(signature);
+ }
+ return new CheckRecordComponentAdapter(
+ api, super.visitRecordComponent(name, descriptor, signature));
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ checkState();
+ checkAccess(
+ access,
+ Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_PRIVATE
+ | Opcodes.ACC_PROTECTED
+ | Opcodes.ACC_STATIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_VOLATILE
+ | Opcodes.ACC_TRANSIENT
+ | Opcodes.ACC_SYNTHETIC
+ | Opcodes.ACC_ENUM
+ | Opcodes.ACC_MANDATED
+ | Opcodes.ACC_DEPRECATED);
+ CheckMethodAdapter.checkUnqualifiedName(version, name, "field name");
+ CheckMethodAdapter.checkDescriptor(version, descriptor, /* canBeVoid = */ false);
+ if (signature != null) {
+ checkFieldSignature(signature);
+ }
+ if (value != null) {
+ CheckMethodAdapter.checkConstant(value);
+ }
+ return new CheckFieldAdapter(api, super.visitField(access, name, descriptor, signature, value));
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ checkState();
+ checkMethodAccess(
+ version,
+ access,
+ Opcodes.ACC_PUBLIC
+ | Opcodes.ACC_PRIVATE
+ | Opcodes.ACC_PROTECTED
+ | Opcodes.ACC_STATIC
+ | Opcodes.ACC_FINAL
+ | Opcodes.ACC_SYNCHRONIZED
+ | Opcodes.ACC_BRIDGE
+ | Opcodes.ACC_VARARGS
+ | Opcodes.ACC_NATIVE
+ | Opcodes.ACC_ABSTRACT
+ | Opcodes.ACC_STRICT
+ | Opcodes.ACC_SYNTHETIC
+ | Opcodes.ACC_MANDATED
+ | Opcodes.ACC_DEPRECATED);
+ if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
+ CheckMethodAdapter.checkMethodIdentifier(version, name, "method name");
+ }
+ CheckMethodAdapter.checkMethodDescriptor(version, descriptor);
+ if (signature != null) {
+ checkMethodSignature(signature);
+ }
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; ++i) {
+ CheckMethodAdapter.checkInternalName(
+ version, exceptions[i], "exception name at index " + i);
+ }
+ }
+ CheckMethodAdapter checkMethodAdapter;
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ if (checkDataFlow) {
+ if (cv instanceof ClassWriter) {
+ methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ api, version, (ClassWriter) cv, methodVisitor);
+ }
+ checkMethodAdapter =
+ new CheckMethodAdapter(api, access, name, descriptor, methodVisitor, labelInsnIndices);
+ } else {
+ checkMethodAdapter = new CheckMethodAdapter(api, methodVisitor, labelInsnIndices);
+ }
+ checkMethodAdapter.version = version;
+ return checkMethodAdapter;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ checkState();
+ CheckMethodAdapter.checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkState();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.CLASS_TYPE_PARAMETER
+ && sort != TypeReference.CLASS_TYPE_PARAMETER_BOUND
+ && sort != TypeReference.CLASS_EXTENDS) {
+ throw new IllegalArgumentException(
+ "Invalid type reference sort 0x" + Integer.toHexString(sort));
+ }
+ checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ checkState();
+ if (attribute == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkState();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /** Checks that the visit method has been called and that visitEnd has not been called. */
+ private void checkState() {
+ if (!visitCalled) {
+ throw new IllegalStateException("Cannot visit member before visit has been called.");
+ }
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot visit member after visitEnd has been called.");
+ }
+ }
+
+ /**
+ * Checks that the given access flags do not contain invalid flags. This method also checks that
+ * mutually incompatible flags are not set simultaneously.
+ *
+ * @param access the access flags to be checked.
+ * @param possibleAccess the valid access flags.
+ */
+ static void checkAccess(final int access, final int possibleAccess) {
+ if ((access & ~possibleAccess) != 0) {
+ throw new IllegalArgumentException("Invalid access flags: " + access);
+ }
+ int publicProtectedPrivate = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE;
+ if (Integer.bitCount(access & publicProtectedPrivate) > 1) {
+ throw new IllegalArgumentException(
+ "public, protected and private are mutually exclusive: " + access);
+ }
+ if (Integer.bitCount(access & (Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT)) > 1) {
+ throw new IllegalArgumentException("final and abstract are mutually exclusive: " + access);
+ }
+ }
+
+ /**
+ * Checks that the given access flags do not contain invalid flags for a method. This method also
+ * checks that mutually incompatible flags are not set simultaneously.
+ *
+ * @param version the class version.
+ * @param access the method access flags to be checked.
+ * @param possibleAccess the valid access flags.
+ */
+ private static void checkMethodAccess(
+ final int version, final int access, final int possibleAccess) {
+ checkAccess(access, possibleAccess);
+ if ((version & 0xFFFF) < Opcodes.V17
+ && Integer.bitCount(access & (Opcodes.ACC_STRICT | Opcodes.ACC_ABSTRACT)) > 1) {
+ throw new IllegalArgumentException("strictfp and abstract are mutually exclusive: " + access);
+ }
+ }
+
+ /**
+ * Checks that the given name is a fully qualified name, using dots.
+ *
+ * @param version the class version.
+ * @param name the name to be checked.
+ * @param source the source of 'name' (e.g 'module' for a module name).
+ */
+ static void checkFullyQualifiedName(final int version, final String name, final String source) {
+ try {
+ int startIndex = 0;
+ int dotIndex;
+ while ((dotIndex = name.indexOf('.', startIndex + 1)) != -1) {
+ CheckMethodAdapter.checkIdentifier(version, name, startIndex, dotIndex, null);
+ startIndex = dotIndex + 1;
+ }
+ CheckMethodAdapter.checkIdentifier(version, name, startIndex, name.length(), null);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "Invalid " + source + " (must be a fully qualified name): " + name, e);
+ }
+ }
+
+ /**
+ * Checks a class signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ */
+ public static void checkClassSignature(final String signature) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // ClassSignature:
+ // [TypeParameters] SuperclassSignature SuperinterfaceSignature*
+ // SuperclassSignature:
+ // ClassTypeSignature
+ // SuperinterfaceSignature:
+ // ClassTypeSignature
+ int pos = 0;
+ if (getChar(signature, 0) == '<') {
+ pos = checkTypeParameters(signature, pos);
+ }
+ pos = checkClassTypeSignature(signature, pos);
+ while (getChar(signature, pos) == 'L') {
+ pos = checkClassTypeSignature(signature, pos);
+ }
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ERROR_AT + pos);
+ }
+ }
+
+ /**
+ * Checks a method signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ */
+ public static void checkMethodSignature(final String signature) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // MethodSignature:
+ // [TypeParameters] ( JavaTypeSignature* ) Result ThrowsSignature*
+ // Result:
+ // JavaTypeSignature
+ // VoidDescriptor
+ // ThrowsSignature:
+ // ^ ClassTypeSignature
+ // ^ TypeVariableSignature
+ int pos = 0;
+ if (getChar(signature, 0) == '<') {
+ pos = checkTypeParameters(signature, pos);
+ }
+ pos = checkChar('(', signature, pos);
+ while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
+ pos = checkJavaTypeSignature(signature, pos);
+ }
+ pos = checkChar(')', signature, pos);
+ if (getChar(signature, pos) == 'V') {
+ ++pos;
+ } else {
+ pos = checkJavaTypeSignature(signature, pos);
+ }
+ while (getChar(signature, pos) == '^') {
+ ++pos;
+ if (getChar(signature, pos) == 'L') {
+ pos = checkClassTypeSignature(signature, pos);
+ } else {
+ pos = checkTypeVariableSignature(signature, pos);
+ }
+ }
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ERROR_AT + pos);
+ }
+ }
+
+ /**
+ * Checks a field signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ */
+ public static void checkFieldSignature(final String signature) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // FieldSignature:
+ // ReferenceTypeSignature
+ int pos = checkReferenceTypeSignature(signature, 0);
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ERROR_AT + pos);
+ }
+ }
+
+ /**
+ * Checks the type parameters of a class or method signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeParameters(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // TypeParameters:
+ // < TypeParameter TypeParameter* >
+ int pos = startPos;
+ pos = checkChar('<', signature, pos);
+ pos = checkTypeParameter(signature, pos);
+ while (getChar(signature, pos) != '>') {
+ pos = checkTypeParameter(signature, pos);
+ }
+ return pos + 1;
+ }
+
+ /**
+ * Checks a type parameter of a class or method signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeParameter(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // TypeParameter:
+ // Identifier ClassBound InterfaceBound*
+ // ClassBound:
+ // : [ReferenceTypeSignature]
+ // InterfaceBound:
+ // : ReferenceTypeSignature
+ int pos = startPos;
+ pos = checkSignatureIdentifier(signature, pos);
+ pos = checkChar(':', signature, pos);
+ if ("L[T".indexOf(getChar(signature, pos)) != -1) {
+ pos = checkReferenceTypeSignature(signature, pos);
+ }
+ while (getChar(signature, pos) == ':') {
+ pos = checkReferenceTypeSignature(signature, pos + 1);
+ }
+ return pos;
+ }
+
+ /**
+ * Checks a reference type signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param pos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkReferenceTypeSignature(final String signature, final int pos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // ReferenceTypeSignature:
+ // ClassTypeSignature
+ // TypeVariableSignature
+ // ArrayTypeSignature
+ // ArrayTypeSignature:
+ // [ JavaTypeSignature
+ switch (getChar(signature, pos)) {
+ case 'L':
+ return checkClassTypeSignature(signature, pos);
+ case '[':
+ return checkJavaTypeSignature(signature, pos + 1);
+ default:
+ return checkTypeVariableSignature(signature, pos);
+ }
+ }
+
+ /**
+ * Checks a class type signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkClassTypeSignature(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // ClassTypeSignature:
+ // L [PackageSpecifier] SimpleClassTypeSignature ClassTypeSignatureSuffix* ;
+ // PackageSpecifier:
+ // Identifier / PackageSpecifier*
+ // SimpleClassTypeSignature:
+ // Identifier [TypeArguments]
+ // ClassTypeSignatureSuffix:
+ // . SimpleClassTypeSignature
+ int pos = startPos;
+ pos = checkChar('L', signature, pos);
+ pos = checkSignatureIdentifier(signature, pos);
+ while (getChar(signature, pos) == '/') {
+ pos = checkSignatureIdentifier(signature, pos + 1);
+ }
+ if (getChar(signature, pos) == '<') {
+ pos = checkTypeArguments(signature, pos);
+ }
+ while (getChar(signature, pos) == '.') {
+ pos = checkSignatureIdentifier(signature, pos + 1);
+ if (getChar(signature, pos) == '<') {
+ pos = checkTypeArguments(signature, pos);
+ }
+ }
+ return checkChar(';', signature, pos);
+ }
+
+ /**
+ * Checks the type arguments in a class type signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeArguments(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // TypeArguments:
+ // < TypeArgument TypeArgument* >
+ int pos = startPos;
+ pos = checkChar('<', signature, pos);
+ pos = checkTypeArgument(signature, pos);
+ while (getChar(signature, pos) != '>') {
+ pos = checkTypeArgument(signature, pos);
+ }
+ return pos + 1;
+ }
+
+ /**
+ * Checks a type argument in a class type signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeArgument(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // TypeArgument:
+ // [WildcardIndicator] ReferenceTypeSignature
+ // *
+ // WildcardIndicator:
+ // +
+ // -
+ int pos = startPos;
+ char c = getChar(signature, pos);
+ if (c == '*') {
+ return pos + 1;
+ } else if (c == '+' || c == '-') {
+ pos++;
+ }
+ return checkReferenceTypeSignature(signature, pos);
+ }
+
+ /**
+ * Checks a type variable signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeVariableSignature(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // TypeVariableSignature:
+ // T Identifier ;
+ int pos = startPos;
+ pos = checkChar('T', signature, pos);
+ pos = checkSignatureIdentifier(signature, pos);
+ return checkChar(';', signature, pos);
+ }
+
+ /**
+ * Checks a Java type signature.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkJavaTypeSignature(final String signature, final int startPos) {
+ // From https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1:
+ // JavaTypeSignature:
+ // ReferenceTypeSignature
+ // BaseType
+ // BaseType:
+ // (one of)
+ // B C D F I J S Z
+ int pos = startPos;
+ switch (getChar(signature, pos)) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ return pos + 1;
+ default:
+ return checkReferenceTypeSignature(signature, pos);
+ }
+ }
+
+ /**
+ * Checks an identifier.
+ *
+ * @param signature a string containing the signature that must be checked.
+ * @param startPos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkSignatureIdentifier(final String signature, final int startPos) {
+ int pos = startPos;
+ while (pos < signature.length() && ".;[/<>:".indexOf(signature.codePointAt(pos)) == -1) {
+ pos = signature.offsetByCodePoints(pos, 1);
+ }
+ if (pos == startPos) {
+ throw new IllegalArgumentException(signature + ": identifier expected at index " + startPos);
+ }
+ return pos;
+ }
+
+ /**
+ * Checks a single character.
+ *
+ * @param c a character.
+ * @param signature a string containing the signature that must be checked.
+ * @param pos index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkChar(final char c, final String signature, final int pos) {
+ if (getChar(signature, pos) == c) {
+ return pos + 1;
+ }
+ throw new IllegalArgumentException(signature + ": '" + c + "' expected at index " + pos);
+ }
+
+ /**
+ * Returns the string character at the given index, or 0.
+ *
+ * @param string a string.
+ * @param pos an index in 'string'.
+ * @return the character at the given index, or 0 if there is no such character.
+ */
+ private static char getChar(final String string, final int pos) {
+ return pos < string.length() ? string.charAt(pos) : (char) 0;
+ }
+
+ /**
+ * Checks the reference to a type in a type annotation.
+ *
+ * @param typeRef a reference to an annotated type.
+ */
+ static void checkTypeRef(final int typeRef) {
+ int mask = 0;
+ switch (typeRef >>> 24) {
+ case TypeReference.CLASS_TYPE_PARAMETER:
+ case TypeReference.METHOD_TYPE_PARAMETER:
+ case TypeReference.METHOD_FORMAL_PARAMETER:
+ mask = 0xFFFF0000;
+ break;
+ case TypeReference.FIELD:
+ case TypeReference.METHOD_RETURN:
+ case TypeReference.METHOD_RECEIVER:
+ case TypeReference.LOCAL_VARIABLE:
+ case TypeReference.RESOURCE_VARIABLE:
+ case TypeReference.INSTANCEOF:
+ case TypeReference.NEW:
+ case TypeReference.CONSTRUCTOR_REFERENCE:
+ case TypeReference.METHOD_REFERENCE:
+ mask = 0xFF000000;
+ break;
+ case TypeReference.CLASS_EXTENDS:
+ case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+ case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+ case TypeReference.THROWS:
+ case TypeReference.EXCEPTION_PARAMETER:
+ mask = 0xFFFFFF00;
+ break;
+ case TypeReference.CAST:
+ case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+ mask = 0xFF0000FF;
+ break;
+ default:
+ break;
+ }
+ if (mask == 0 || (typeRef & ~mask) != 0) {
+ throw new IllegalArgumentException(
+ "Invalid type reference 0x" + Integer.toHexString(typeRef));
+ }
+ }
+
+ /**
+ * Returns the package name of an internal name.
+ *
+ * @param name an internal name.
+ * @return the package name or "" if there is no package.
+ */
+ private static String packageName(final String name) {
+ int index = name.lastIndexOf('/');
+ if (index == -1) {
+ return "";
+ }
+ return name.substring(0, index);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Static verification methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Checks the given class.
+ *
+ * <p>Usage: CheckClassAdapter &lt;binary class name or class file name&gt;
+ *
+ * @param args the command line arguments.
+ * @throws IOException if the class cannot be found, or if an IO exception occurs.
+ */
+ public static void main(final String[] args) throws IOException {
+ main(args, new PrintWriter(System.err, true));
+ }
+
+ /**
+ * Checks the given class.
+ *
+ * @param args the command line arguments.
+ * @param logger where to log errors.
+ * @throws IOException if the class cannot be found, or if an IO exception occurs.
+ */
+ static void main(final String[] args, final PrintWriter logger) throws IOException {
+ if (args.length != 1) {
+ logger.println(USAGE);
+ return;
+ }
+
+ ClassReader classReader;
+ if (args[0].endsWith(".class")) {
+ // Can't fix PMD warning for 1.5 compatibility.
+ try (InputStream inputStream = new FileInputStream(args[0])) { // NOPMD(AvoidFileStream)
+ classReader = new ClassReader(inputStream);
+ }
+ } else {
+ classReader = new ClassReader(args[0]);
+ }
+
+ verify(classReader, false, logger);
+ }
+
+ /**
+ * Checks the given class.
+ *
+ * @param classReader the class to be checked.
+ * @param printResults whether to print the results of the bytecode verification.
+ * @param printWriter where the results (or the stack trace in case of error) must be printed.
+ */
+ public static void verify(
+ final ClassReader classReader, final boolean printResults, final PrintWriter printWriter) {
+ verify(classReader, null, printResults, printWriter);
+ }
+
+ /**
+ * Checks the given class.
+ *
+ * @param classReader the class to be checked.
+ * @param loader a <code>ClassLoader</code> which will be used to load referenced classes. May be
+ * {@literal null}.
+ * @param printResults whether to print the results of the bytecode verification.
+ * @param printWriter where the results (or the stack trace in case of error) must be printed.
+ */
+ public static void verify(
+ final ClassReader classReader,
+ final ClassLoader loader,
+ final boolean printResults,
+ final PrintWriter printWriter) {
+ ClassNode classNode = new ClassNode();
+ classReader.accept(
+ new CheckClassAdapter(/*latest*/ Opcodes.ASM10_EXPERIMENTAL, classNode, false) {},
+ ClassReader.SKIP_DEBUG);
+
+ Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName);
+ List<MethodNode> methods = classNode.methods;
+
+ List<Type> interfaces = new ArrayList<>();
+ for (String interfaceName : classNode.interfaces) {
+ interfaces.add(Type.getObjectType(interfaceName));
+ }
+
+ for (MethodNode method : methods) {
+ SimpleVerifier verifier =
+ new SimpleVerifier(
+ Type.getObjectType(classNode.name),
+ syperType,
+ interfaces,
+ (classNode.access & Opcodes.ACC_INTERFACE) != 0);
+ Analyzer<BasicValue> analyzer = new Analyzer<>(verifier);
+ if (loader != null) {
+ verifier.setClassLoader(loader);
+ }
+ try {
+ analyzer.analyze(classNode.name, method);
+ } catch (AnalyzerException e) {
+ e.printStackTrace(printWriter);
+ }
+ if (printResults) {
+ printAnalyzerResult(method, analyzer, printWriter);
+ }
+ }
+ printWriter.flush();
+ }
+
+ static void printAnalyzerResult(
+ final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
+ Textifier textifier = new Textifier();
+ TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
+
+ printWriter.println(method.name + method.desc);
+ for (int i = 0; i < method.instructions.size(); ++i) {
+ method.instructions.get(i).accept(traceMethodVisitor);
+
+ StringBuilder stringBuilder = new StringBuilder();
+ Frame<BasicValue> frame = analyzer.getFrames()[i];
+ if (frame == null) {
+ stringBuilder.append('?');
+ } else {
+ for (int j = 0; j < frame.getLocals(); ++j) {
+ stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
+ }
+ stringBuilder.append(" : ");
+ for (int j = 0; j < frame.getStackSize(); ++j) {
+ stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
+ }
+ }
+ while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
+ stringBuilder.append(' ');
+ }
+ printWriter.print(Integer.toString(i + 100000).substring(1));
+ printWriter.print(
+ " " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
+ }
+ for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
+ tryCatchBlock.accept(traceMethodVisitor);
+ printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
+ }
+ printWriter.println();
+ }
+
+ private static String getUnqualifiedName(final String name) {
+ int lastSlashIndex = name.lastIndexOf('/');
+ if (lastSlashIndex == -1) {
+ return name;
+ } else {
+ int endIndex = name.length();
+ if (name.charAt(endIndex - 1) == ';') {
+ endIndex--;
+ }
+ int lastBracketIndex = name.lastIndexOf('[');
+ if (lastBracketIndex == -1) {
+ return name.substring(lastSlashIndex + 1, endIndex);
+ }
+ return name.substring(0, lastBracketIndex + 1) + name.substring(lastSlashIndex + 1, endIndex);
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java
new file mode 100644
index 00000000..6988f506
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java
@@ -0,0 +1,116 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+
+/**
+ * A {@link FieldVisitor} that checks that its methods are properly used.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckFieldAdapter extends FieldVisitor {
+
+ /** Whether the {@link #visitEnd} method has been called. */
+ private boolean visitEndCalled;
+
+ /**
+ * Constructs a new {@link CheckFieldAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #CheckFieldAdapter(int, FieldVisitor)} version.
+ *
+ * @param fieldVisitor the field visitor to which this adapter must delegate calls.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public CheckFieldAdapter(final FieldVisitor fieldVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, fieldVisitor);
+ if (getClass() != CheckFieldAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckFieldAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param fieldVisitor the field visitor to which this adapter must delegate calls.
+ */
+ protected CheckFieldAdapter(final int api, final FieldVisitor fieldVisitor) {
+ super(api, fieldVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ // Annotations can only appear in V1_5 or more classes.
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.FIELD) {
+ throw new IllegalArgumentException(
+ "Invalid type reference sort 0x" + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ checkVisitEndNotCalled();
+ if (attribute == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkVisitEndNotCalled();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ private void checkVisitEndNotCalled() {
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckFrameAnalyzer.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckFrameAnalyzer.java
new file mode 100644
index 00000000..6a5b1de6
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckFrameAnalyzer.java
@@ -0,0 +1,477 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.Collections;
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FrameNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.objectweb.asm.tree.analysis.Frame;
+import org.objectweb.asm.tree.analysis.Interpreter;
+import org.objectweb.asm.tree.analysis.Value;
+
+/**
+ * An {@link Analyzer} subclass which checks that methods provide stack map frames where expected
+ * (i.e. at jump target and after instructions without immediate successor), and that these stack
+ * map frames are valid (for the provided interpreter; they may still be invalid for the JVM, if the
+ * {@link Interpreter} uses a simplified type system compared to the JVM verifier). This is done in
+ * two steps:
+ *
+ * <ul>
+ * <li>First, the stack map frames in {@link FrameNode}s are expanded, and stored at their
+ * respective instruction offsets. The expansion process uncompresses the APPEND, CHOP and
+ * SAME frames to FULL frames. It also converts the stack map frame verification types to
+ * {@link Value}s, via the provided {@link Interpreter}. The expansion is done in {@link
+ * #expandFrames}, by looking at each {@link FrameNode} in sequence (compressed frames are
+ * defined relatively to the previous {@link FrameNode}, or the implicit first frame). The
+ * actual decompression is done in {@link #expandFrame}, and the type conversion in {@link
+ * #newFrameValue}.
+ * <li>Next, the method instructions are checked in sequence. Starting from the implicit initial
+ * frame, the execution of each instruction <em>i</em> is simulated on the current stack map
+ * frame, with the {@link Frame#execute} method. This gives a new stack map frame <em>f</em>,
+ * representing the stack map frame state after the execution of <em>i</em>. Then:
+ * <ul>
+ * <li>If there is a next instruction and if the control flow cannot continue to it (e.g. if
+ * <em>i</em> is a RETURN or an ATHROW, for instance): an existing stack map frame
+ * <em>f0</em> (coming from the first step) is expected after <em>i</em>.
+ * <li>If there is a next instruction and if the control flow can continue to it (e.g. if
+ * <em>i</em> is a ALOAD, for instance): either there an existing stack map frame
+ * <em>f0</em> (coming from the first step) after <em>i</em>, or there is none. In the
+ * first case <em>f</em> and <em>f0</em> must be <em>compatible</em>: the types in
+ * <em>f</em> must be sub types of the corresponding types in the existing frame
+ * <em>f0</em> (otherwise an exception is thrown). In the second case, <em>f0</em> is
+ * simply set to the value of <em>f</em>.
+ * <li>If the control flow can continue to some instruction <em>j</em> (e.g. if <em>i</em>
+ * is an IF_EQ, for instance): an existing stack map frame <em>f0</em> (coming from the
+ * first step) is expected at <em>j</em>, which must be compatible with <em>f</em> (as
+ * defined previously).
+ * </ul>
+ * The sequential loop over the instructions is done in {@link #init}, which is called from
+ * the {@link Analyzer#analyze} method. Cases where the control flow cannot continue to the
+ * next instruction are handled in {@link #endControlFlow}. Cases where the control flow can
+ * continue to the next instruction, or jump to another instruction, are handled in {@link
+ * #checkFrame}. This method checks that an existing stack map frame is present when required,
+ * and checks the stack map frames compatibility with {@link #checkMerge}.
+ * </ul>
+ *
+ * @author Eric Bruneton
+ * @param <V> type of the {@link Value} used for the analysis.
+ */
+class CheckFrameAnalyzer<V extends Value> extends Analyzer<V> {
+
+ /** The interpreter to use to symbolically interpret the bytecode instructions. */
+ private final Interpreter<V> interpreter;
+
+ /** The instructions of the currently analyzed method. */
+ private InsnList insnList;
+
+ /**
+ * The number of locals in the last stack map frame processed by {@link expandFrame}. Long and
+ * double values are represented with two elements.
+ */
+ private int currentLocals;
+
+ CheckFrameAnalyzer(final Interpreter<V> interpreter) {
+ super(interpreter);
+ this.interpreter = interpreter;
+ }
+
+ @Override
+ protected void init(final String owner, final MethodNode method) throws AnalyzerException {
+ insnList = method.instructions;
+ currentLocals = Type.getArgumentsAndReturnSizes(method.desc) >> 2;
+
+ Frame<V>[] frames = getFrames();
+ Frame<V> currentFrame = frames[0];
+ expandFrames(owner, method, currentFrame);
+ for (int insnIndex = 0; insnIndex < insnList.size(); ++insnIndex) {
+ Frame<V> oldFrame = frames[insnIndex];
+
+ // Simulate the execution of this instruction.
+ AbstractInsnNode insnNode = null;
+ try {
+ insnNode = method.instructions.get(insnIndex);
+ int insnOpcode = insnNode.getOpcode();
+ int insnType = insnNode.getType();
+
+ if (insnType == AbstractInsnNode.LABEL
+ || insnType == AbstractInsnNode.LINE
+ || insnType == AbstractInsnNode.FRAME) {
+ checkFrame(insnIndex + 1, oldFrame, /* requireFrame = */ false);
+ } else {
+ currentFrame.init(oldFrame).execute(insnNode, interpreter);
+
+ if (insnNode instanceof JumpInsnNode) {
+ if (insnOpcode == JSR) {
+ throw new AnalyzerException(insnNode, "JSR instructions are unsupported");
+ }
+ JumpInsnNode jumpInsn = (JumpInsnNode) insnNode;
+ int targetInsnIndex = insnList.indexOf(jumpInsn.label);
+ checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
+ if (insnOpcode == GOTO) {
+ endControlFlow(insnIndex);
+ } else {
+ checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false);
+ }
+ } else if (insnNode instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) insnNode;
+ int targetInsnIndex = insnList.indexOf(lookupSwitchInsn.dflt);
+ checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
+ for (int i = 0; i < lookupSwitchInsn.labels.size(); ++i) {
+ LabelNode label = lookupSwitchInsn.labels.get(i);
+ targetInsnIndex = insnList.indexOf(label);
+ currentFrame.initJumpTarget(insnOpcode, label);
+ checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
+ }
+ endControlFlow(insnIndex);
+ } else if (insnNode instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) insnNode;
+ int targetInsnIndex = insnList.indexOf(tableSwitchInsn.dflt);
+ currentFrame.initJumpTarget(insnOpcode, tableSwitchInsn.dflt);
+ checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
+ newControlFlowEdge(insnIndex, targetInsnIndex);
+ for (int i = 0; i < tableSwitchInsn.labels.size(); ++i) {
+ LabelNode label = tableSwitchInsn.labels.get(i);
+ currentFrame.initJumpTarget(insnOpcode, label);
+ targetInsnIndex = insnList.indexOf(label);
+ checkFrame(targetInsnIndex, currentFrame, /* requireFrame = */ true);
+ }
+ endControlFlow(insnIndex);
+ } else if (insnOpcode == RET) {
+ throw new AnalyzerException(insnNode, "RET instructions are unsupported");
+ } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
+ checkFrame(insnIndex + 1, currentFrame, /* requireFrame = */ false);
+ } else {
+ endControlFlow(insnIndex);
+ }
+ }
+
+ List<TryCatchBlockNode> insnHandlers = getHandlers(insnIndex);
+ if (insnHandlers != null) {
+ for (TryCatchBlockNode tryCatchBlock : insnHandlers) {
+ Type catchType;
+ if (tryCatchBlock.type == null) {
+ catchType = Type.getObjectType("java/lang/Throwable");
+ } else {
+ catchType = Type.getObjectType(tryCatchBlock.type);
+ }
+ Frame<V> handler = newFrame(oldFrame);
+ handler.clearStack();
+ handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType));
+ checkFrame(insnList.indexOf(tryCatchBlock.handler), handler, /* requireFrame = */ true);
+ }
+ }
+
+ if (!hasNextJvmInsnOrFrame(insnIndex)) {
+ break;
+ }
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException(
+ e.node, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
+ } catch (RuntimeException e) {
+ // DontCheck(IllegalCatch): can't be fixed, for backward compatibility.
+ throw new AnalyzerException(
+ insnNode, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Expands the {@link FrameNode} "instructions" of the given method into {@link Frame} objects and
+ * stores them at the corresponding indices of the {@link #frames} array. The expanded frames are
+ * also associated with the label and line number nodes immediately preceding each frame node.
+ *
+ * @param owner the internal name of the class to which 'method' belongs.
+ * @param method the method whose frames must be expanded.
+ * @param initialFrame the implicit initial frame of 'method'.
+ * @throws AnalyzerException if the stack map frames of 'method', i.e. its FrameNode
+ * "instructions", are invalid.
+ */
+ private void expandFrames(
+ final String owner, final MethodNode method, final Frame<V> initialFrame)
+ throws AnalyzerException {
+ int lastJvmOrFrameInsnIndex = -1;
+ Frame<V> currentFrame = initialFrame;
+ int currentInsnIndex = 0;
+ for (AbstractInsnNode insnNode : method.instructions) {
+ if (insnNode instanceof FrameNode) {
+ try {
+ currentFrame = expandFrame(owner, currentFrame, (FrameNode) insnNode);
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException(
+ e.node, "Error at instruction " + currentInsnIndex + ": " + e.getMessage(), e);
+ }
+ for (int index = lastJvmOrFrameInsnIndex + 1; index <= currentInsnIndex; ++index) {
+ getFrames()[index] = currentFrame;
+ }
+ }
+ if (isJvmInsnNode(insnNode) || insnNode instanceof FrameNode) {
+ lastJvmOrFrameInsnIndex = currentInsnIndex;
+ }
+ currentInsnIndex += 1;
+ }
+ }
+
+ /**
+ * Returns the expanded representation of the given {@link FrameNode}.
+ *
+ * @param owner the internal name of the class to which 'frameNode' belongs.
+ * @param previousFrame the frame before 'frameNode', in expanded form.
+ * @param frameNode a possibly compressed stack map frame.
+ * @return the expanded version of 'frameNode'.
+ * @throws AnalyzerException if 'frameNode' is invalid.
+ */
+ private Frame<V> expandFrame(
+ final String owner, final Frame<V> previousFrame, final FrameNode frameNode)
+ throws AnalyzerException {
+ Frame<V> frame = newFrame(previousFrame);
+ List<Object> locals = frameNode.local == null ? Collections.emptyList() : frameNode.local;
+ int currentLocal = currentLocals;
+ switch (frameNode.type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ currentLocal = 0;
+ // fall through
+ case Opcodes.F_APPEND:
+ for (Object type : locals) {
+ V value = newFrameValue(owner, frameNode, type);
+ if (currentLocal + value.getSize() > frame.getLocals()) {
+ throw new AnalyzerException(frameNode, "Cannot append more locals than maxLocals");
+ }
+ frame.setLocal(currentLocal++, value);
+ if (value.getSize() == 2) {
+ frame.setLocal(currentLocal++, interpreter.newValue(null));
+ }
+ }
+ break;
+ case Opcodes.F_CHOP:
+ for (Object unusedType : locals) {
+ if (currentLocal <= 0) {
+ throw new AnalyzerException(frameNode, "Cannot chop more locals than defined");
+ }
+ if (currentLocal > 1 && frame.getLocal(currentLocal - 2).getSize() == 2) {
+ currentLocal -= 2;
+ } else {
+ currentLocal -= 1;
+ }
+ }
+ break;
+ case Opcodes.F_SAME:
+ case Opcodes.F_SAME1:
+ break;
+ default:
+ throw new AnalyzerException(frameNode, "Illegal frame type " + frameNode.type);
+ }
+ currentLocals = currentLocal;
+ while (currentLocal < frame.getLocals()) {
+ frame.setLocal(currentLocal++, interpreter.newValue(null));
+ }
+
+ List<Object> stack = frameNode.stack == null ? Collections.emptyList() : frameNode.stack;
+ frame.clearStack();
+ for (Object type : stack) {
+ frame.push(newFrameValue(owner, frameNode, type));
+ }
+ return frame;
+ }
+
+ /**
+ * Creates a new {@link Value} that represents the given stack map frame type.
+ *
+ * @param owner the internal name of the class to which 'frameNode' belongs.
+ * @param frameNode the stack map frame to which 'type' belongs.
+ * @param type an Integer, String or LabelNode object representing a primitive, reference or
+ * uninitialized a stack map frame type, respectively. See {@link FrameNode}.
+ * @return a value that represents the given type.
+ * @throws AnalyzerException if 'type' is an invalid stack map frame type.
+ */
+ private V newFrameValue(final String owner, final FrameNode frameNode, final Object type)
+ throws AnalyzerException {
+ if (type == Opcodes.TOP) {
+ return interpreter.newValue(null);
+ } else if (type == Opcodes.INTEGER) {
+ return interpreter.newValue(Type.INT_TYPE);
+ } else if (type == Opcodes.FLOAT) {
+ return interpreter.newValue(Type.FLOAT_TYPE);
+ } else if (type == Opcodes.LONG) {
+ return interpreter.newValue(Type.LONG_TYPE);
+ } else if (type == Opcodes.DOUBLE) {
+ return interpreter.newValue(Type.DOUBLE_TYPE);
+ } else if (type == Opcodes.NULL) {
+ return interpreter.newOperation(new InsnNode(Opcodes.ACONST_NULL));
+ } else if (type == Opcodes.UNINITIALIZED_THIS) {
+ return interpreter.newValue(Type.getObjectType(owner));
+ } else if (type instanceof String) {
+ return interpreter.newValue(Type.getObjectType((String) type));
+ } else if (type instanceof LabelNode) {
+ AbstractInsnNode referencedNode = (LabelNode) type;
+ while (referencedNode != null && !isJvmInsnNode(referencedNode)) {
+ referencedNode = referencedNode.getNext();
+ }
+ if (referencedNode == null || referencedNode.getOpcode() != Opcodes.NEW) {
+ throw new AnalyzerException(frameNode, "LabelNode does not designate a NEW instruction");
+ }
+ return interpreter.newValue(Type.getObjectType(((TypeInsnNode) referencedNode).desc));
+ }
+ throw new AnalyzerException(frameNode, "Illegal stack map frame value " + type);
+ }
+
+ /**
+ * Checks that the given frame is compatible with the frame at the given instruction index, if
+ * any. If there is no frame at this instruction index and none is required, the frame at
+ * 'insnIndex' is set to the given frame. Otherwise, if the merge of the two frames is not equal
+ * to the current frame at 'insnIndex', an exception is thrown.
+ *
+ * @param insnIndex an instruction index.
+ * @param frame a frame. This frame is left unchanged by this method.
+ * @param requireFrame whether a frame must already exist or not in {@link #frames} at
+ * 'insnIndex'.
+ * @throws AnalyzerException if the frames have incompatible sizes or if the frame at 'insnIndex'
+ * is missing (if required) or not compatible with 'frame'.
+ */
+ private void checkFrame(final int insnIndex, final Frame<V> frame, final boolean requireFrame)
+ throws AnalyzerException {
+ Frame<V> oldFrame = getFrames()[insnIndex];
+ if (oldFrame == null) {
+ if (requireFrame) {
+ throw new AnalyzerException(null, "Expected stack map frame at instruction " + insnIndex);
+ }
+ getFrames()[insnIndex] = newFrame(frame);
+ } else {
+ String error = checkMerge(frame, oldFrame);
+ if (error != null) {
+ throw new AnalyzerException(
+ null,
+ "Stack map frame incompatible with frame at instruction "
+ + insnIndex
+ + " ("
+ + error
+ + ")");
+ }
+ }
+ }
+
+ /**
+ * Checks that merging the two given frames would not produce any change, i.e. that the types in
+ * the source frame are sub types of the corresponding types in the destination frame.
+ *
+ * @param srcFrame a source frame. This frame is left unchanged by this method.
+ * @param dstFrame a destination frame. This frame is left unchanged by this method.
+ * @return an error message if the frames have incompatible sizes, or if a type in the source
+ * frame is not a sub type of the corresponding type in the destination frame. Returns
+ * {@literal null} otherwise.
+ */
+ private String checkMerge(final Frame<V> srcFrame, final Frame<V> dstFrame) {
+ int numLocals = srcFrame.getLocals();
+ if (numLocals != dstFrame.getLocals()) {
+ throw new AssertionError();
+ }
+ for (int i = 0; i < numLocals; ++i) {
+ V v = interpreter.merge(srcFrame.getLocal(i), dstFrame.getLocal(i));
+ if (!v.equals(dstFrame.getLocal(i))) {
+ return "incompatible types at local "
+ + i
+ + ": "
+ + srcFrame.getLocal(i)
+ + " and "
+ + dstFrame.getLocal(i);
+ }
+ }
+ int numStack = srcFrame.getStackSize();
+ if (numStack != dstFrame.getStackSize()) {
+ return "incompatible stack heights";
+ }
+ for (int i = 0; i < numStack; ++i) {
+ V v = interpreter.merge(srcFrame.getStack(i), dstFrame.getStack(i));
+ if (!v.equals(dstFrame.getStack(i))) {
+ return "incompatible types at stack item "
+ + i
+ + ": "
+ + srcFrame.getStack(i)
+ + " and "
+ + dstFrame.getStack(i);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Ends the control flow graph at the given instruction. This method checks that there is an
+ * existing frame for the next instruction, if any.
+ *
+ * @param insnIndex an instruction index.
+ * @throws AnalyzerException if 'insnIndex' is not the last instruction and there is no frame at
+ * 'insnIndex' + 1 in {@link #getFrames}.
+ */
+ private void endControlFlow(final int insnIndex) throws AnalyzerException {
+ if (hasNextJvmInsnOrFrame(insnIndex) && getFrames()[insnIndex + 1] == null) {
+ throw new AnalyzerException(
+ null, "Expected stack map frame at instruction " + (insnIndex + 1));
+ }
+ }
+
+ /**
+ * Returns true if the given instruction is followed by a JVM instruction or a by stack map frame.
+ *
+ * @param insnIndex an instruction index.
+ * @return true if 'insnIndex' is followed by a JVM instruction or a by stack map frame.
+ */
+ private boolean hasNextJvmInsnOrFrame(final int insnIndex) {
+ AbstractInsnNode insn = insnList.get(insnIndex).getNext();
+ while (insn != null) {
+ if (isJvmInsnNode(insn) || insn instanceof FrameNode) {
+ return true;
+ }
+ insn = insn.getNext();
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the given instruction node corresponds to a real JVM instruction.
+ *
+ * @param insnNode an instruction node.
+ * @return true except for label, line number and stack map frame nodes.
+ */
+ private static boolean isJvmInsnNode(final AbstractInsnNode insnNode) {
+ return insnNode.getOpcode() >= 0;
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java
new file mode 100644
index 00000000..b6759073
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java
@@ -0,0 +1,1483 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.objectweb.asm.tree.analysis.BasicValue;
+import org.objectweb.asm.tree.analysis.BasicVerifier;
+
+/**
+ * A {@link MethodVisitor} that checks that its methods are properly used. More precisely this
+ * method adapter checks each instruction individually, i.e., each visit method checks some
+ * preconditions based <i>only</i> on its arguments - such as the fact that the given opcode is
+ * correct for a given visit method. This adapter can also perform some basic data flow checks (more
+ * precisely those that can be performed without the full class hierarchy - see {@link
+ * org.objectweb.asm.tree.analysis.BasicVerifier}). For instance in a method whose signature is
+ * {@code void m ()}, the invalid instruction IRETURN, or the invalid sequence IADD L2I will be
+ * detected if the data flow checks are enabled. These checks are enabled by using the {@link
+ * #CheckMethodAdapter(int,String,String,MethodVisitor,Map)} constructor. They are not performed if
+ * any other constructor is used.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckMethodAdapter extends MethodVisitor {
+
+ /** The 'generic' instruction visit methods (i.e. those that take an opcode argument). */
+ private enum Method {
+ VISIT_INSN,
+ VISIT_INT_INSN,
+ VISIT_VAR_INSN,
+ VISIT_TYPE_INSN,
+ VISIT_FIELD_INSN,
+ VISIT_METHOD_INSN,
+ VISIT_JUMP_INSN
+ }
+
+ /** The method to use to visit each instruction. Only generic methods are represented here. */
+ private static final Method[] OPCODE_METHODS = {
+ Method.VISIT_INSN, // NOP
+ Method.VISIT_INSN, // ACONST_NULL
+ Method.VISIT_INSN, // ICONST_M1
+ Method.VISIT_INSN, // ICONST_0
+ Method.VISIT_INSN, // ICONST_1
+ Method.VISIT_INSN, // ICONST_2
+ Method.VISIT_INSN, // ICONST_3
+ Method.VISIT_INSN, // ICONST_4
+ Method.VISIT_INSN, // ICONST_5
+ Method.VISIT_INSN, // LCONST_0
+ Method.VISIT_INSN, // LCONST_1
+ Method.VISIT_INSN, // FCONST_0
+ Method.VISIT_INSN, // FCONST_1
+ Method.VISIT_INSN, // FCONST_2
+ Method.VISIT_INSN, // DCONST_0
+ Method.VISIT_INSN, // DCONST_1
+ Method.VISIT_INT_INSN, // BIPUSH
+ Method.VISIT_INT_INSN, // SIPUSH
+ null, // LDC
+ null, // LDC_W
+ null, // LDC2_W
+ Method.VISIT_VAR_INSN, // ILOAD
+ Method.VISIT_VAR_INSN, // LLOAD
+ Method.VISIT_VAR_INSN, // FLOAD
+ Method.VISIT_VAR_INSN, // DLOAD
+ Method.VISIT_VAR_INSN, // ALOAD
+ null, // ILOAD_0
+ null, // ILOAD_1
+ null, // ILOAD_2
+ null, // ILOAD_3
+ null, // LLOAD_0
+ null, // LLOAD_1
+ null, // LLOAD_2
+ null, // LLOAD_3
+ null, // FLOAD_0
+ null, // FLOAD_1
+ null, // FLOAD_2
+ null, // FLOAD_3
+ null, // DLOAD_0
+ null, // DLOAD_1
+ null, // DLOAD_2
+ null, // DLOAD_3
+ null, // ALOAD_0
+ null, // ALOAD_1
+ null, // ALOAD_2
+ null, // ALOAD_3
+ Method.VISIT_INSN, // IALOAD
+ Method.VISIT_INSN, // LALOAD
+ Method.VISIT_INSN, // FALOAD
+ Method.VISIT_INSN, // DALOAD
+ Method.VISIT_INSN, // AALOAD
+ Method.VISIT_INSN, // BALOAD
+ Method.VISIT_INSN, // CALOAD
+ Method.VISIT_INSN, // SALOAD
+ Method.VISIT_VAR_INSN, // ISTORE
+ Method.VISIT_VAR_INSN, // LSTORE
+ Method.VISIT_VAR_INSN, // FSTORE
+ Method.VISIT_VAR_INSN, // DSTORE
+ Method.VISIT_VAR_INSN, // ASTORE
+ null, // ISTORE_0
+ null, // ISTORE_1
+ null, // ISTORE_2
+ null, // ISTORE_3
+ null, // LSTORE_0
+ null, // LSTORE_1
+ null, // LSTORE_2
+ null, // LSTORE_3
+ null, // FSTORE_0
+ null, // FSTORE_1
+ null, // FSTORE_2
+ null, // FSTORE_3
+ null, // DSTORE_0
+ null, // DSTORE_1
+ null, // DSTORE_2
+ null, // DSTORE_3
+ null, // ASTORE_0
+ null, // ASTORE_1
+ null, // ASTORE_2
+ null, // ASTORE_3
+ Method.VISIT_INSN, // IASTORE
+ Method.VISIT_INSN, // LASTORE
+ Method.VISIT_INSN, // FASTORE
+ Method.VISIT_INSN, // DASTORE
+ Method.VISIT_INSN, // AASTORE
+ Method.VISIT_INSN, // BASTORE
+ Method.VISIT_INSN, // CASTORE
+ Method.VISIT_INSN, // SASTORE
+ Method.VISIT_INSN, // POP
+ Method.VISIT_INSN, // POP2
+ Method.VISIT_INSN, // DUP
+ Method.VISIT_INSN, // DUP_X1
+ Method.VISIT_INSN, // DUP_X2
+ Method.VISIT_INSN, // DUP2
+ Method.VISIT_INSN, // DUP2_X1
+ Method.VISIT_INSN, // DUP2_X2
+ Method.VISIT_INSN, // SWAP
+ Method.VISIT_INSN, // IADD
+ Method.VISIT_INSN, // LADD
+ Method.VISIT_INSN, // FADD
+ Method.VISIT_INSN, // DADD
+ Method.VISIT_INSN, // ISUB
+ Method.VISIT_INSN, // LSUB
+ Method.VISIT_INSN, // FSUB
+ Method.VISIT_INSN, // DSUB
+ Method.VISIT_INSN, // IMUL
+ Method.VISIT_INSN, // LMUL
+ Method.VISIT_INSN, // FMUL
+ Method.VISIT_INSN, // DMUL
+ Method.VISIT_INSN, // IDIV
+ Method.VISIT_INSN, // LDIV
+ Method.VISIT_INSN, // FDIV
+ Method.VISIT_INSN, // DDIV
+ Method.VISIT_INSN, // IREM
+ Method.VISIT_INSN, // LREM
+ Method.VISIT_INSN, // FREM
+ Method.VISIT_INSN, // DREM
+ Method.VISIT_INSN, // INEG
+ Method.VISIT_INSN, // LNEG
+ Method.VISIT_INSN, // FNEG
+ Method.VISIT_INSN, // DNEG
+ Method.VISIT_INSN, // ISHL
+ Method.VISIT_INSN, // LSHL
+ Method.VISIT_INSN, // ISHR
+ Method.VISIT_INSN, // LSHR
+ Method.VISIT_INSN, // IUSHR
+ Method.VISIT_INSN, // LUSHR
+ Method.VISIT_INSN, // IAND
+ Method.VISIT_INSN, // LAND
+ Method.VISIT_INSN, // IOR
+ Method.VISIT_INSN, // LOR
+ Method.VISIT_INSN, // IXOR
+ Method.VISIT_INSN, // LXOR
+ null, // IINC
+ Method.VISIT_INSN, // I2L
+ Method.VISIT_INSN, // I2F
+ Method.VISIT_INSN, // I2D
+ Method.VISIT_INSN, // L2I
+ Method.VISIT_INSN, // L2F
+ Method.VISIT_INSN, // L2D
+ Method.VISIT_INSN, // F2I
+ Method.VISIT_INSN, // F2L
+ Method.VISIT_INSN, // F2D
+ Method.VISIT_INSN, // D2I
+ Method.VISIT_INSN, // D2L
+ Method.VISIT_INSN, // D2F
+ Method.VISIT_INSN, // I2B
+ Method.VISIT_INSN, // I2C
+ Method.VISIT_INSN, // I2S
+ Method.VISIT_INSN, // LCMP
+ Method.VISIT_INSN, // FCMPL
+ Method.VISIT_INSN, // FCMPG
+ Method.VISIT_INSN, // DCMPL
+ Method.VISIT_INSN, // DCMPG
+ Method.VISIT_JUMP_INSN, // IFEQ
+ Method.VISIT_JUMP_INSN, // IFNE
+ Method.VISIT_JUMP_INSN, // IFLT
+ Method.VISIT_JUMP_INSN, // IFGE
+ Method.VISIT_JUMP_INSN, // IFGT
+ Method.VISIT_JUMP_INSN, // IFLE
+ Method.VISIT_JUMP_INSN, // IF_ICMPEQ
+ Method.VISIT_JUMP_INSN, // IF_ICMPNE
+ Method.VISIT_JUMP_INSN, // IF_ICMPLT
+ Method.VISIT_JUMP_INSN, // IF_ICMPGE
+ Method.VISIT_JUMP_INSN, // IF_ICMPGT
+ Method.VISIT_JUMP_INSN, // IF_ICMPLE
+ Method.VISIT_JUMP_INSN, // IF_ACMPEQ
+ Method.VISIT_JUMP_INSN, // IF_ACMPNE
+ Method.VISIT_JUMP_INSN, // GOTO
+ Method.VISIT_JUMP_INSN, // JSR
+ Method.VISIT_VAR_INSN, // RET
+ null, // TABLESWITCH
+ null, // LOOKUPSWITCH
+ Method.VISIT_INSN, // IRETURN
+ Method.VISIT_INSN, // LRETURN
+ Method.VISIT_INSN, // FRETURN
+ Method.VISIT_INSN, // DRETURN
+ Method.VISIT_INSN, // ARETURN
+ Method.VISIT_INSN, // RETURN
+ Method.VISIT_FIELD_INSN, // GETSTATIC
+ Method.VISIT_FIELD_INSN, // PUTSTATIC
+ Method.VISIT_FIELD_INSN, // GETFIELD
+ Method.VISIT_FIELD_INSN, // PUTFIELD
+ Method.VISIT_METHOD_INSN, // INVOKEVIRTUAL
+ Method.VISIT_METHOD_INSN, // INVOKESPECIAL
+ Method.VISIT_METHOD_INSN, // INVOKESTATIC
+ Method.VISIT_METHOD_INSN, // INVOKEINTERFACE
+ null, // INVOKEDYNAMIC
+ Method.VISIT_TYPE_INSN, // NEW
+ Method.VISIT_INT_INSN, // NEWARRAY
+ Method.VISIT_TYPE_INSN, // ANEWARRAY
+ Method.VISIT_INSN, // ARRAYLENGTH
+ Method.VISIT_INSN, // ATHROW
+ Method.VISIT_TYPE_INSN, // CHECKCAST
+ Method.VISIT_TYPE_INSN, // INSTANCEOF
+ Method.VISIT_INSN, // MONITORENTER
+ Method.VISIT_INSN, // MONITOREXIT
+ null, // WIDE
+ null, // MULTIANEWARRAY
+ Method.VISIT_JUMP_INSN, // IFNULL
+ Method.VISIT_JUMP_INSN // IFNONNULL
+ };
+
+ private static final String INVALID = "Invalid ";
+ private static final String INVALID_DESCRIPTOR = "Invalid descriptor: ";
+ private static final String INVALID_TYPE_REFERENCE = "Invalid type reference sort 0x";
+ private static final String INVALID_LOCAL_VARIABLE_INDEX = "Invalid local variable index";
+ private static final String MUST_NOT_BE_NULL_OR_EMPTY = " (must not be null or empty)";
+ private static final String START_LABEL = "start label";
+ private static final String END_LABEL = "end label";
+
+ /** The class version number. */
+ public int version;
+
+ /** The access flags of the visited method. */
+ private int access;
+
+ /**
+ * The number of method parameters that can have runtime visible annotations. 0 means that all the
+ * parameters from the method descriptor can have annotations.
+ */
+ private int visibleAnnotableParameterCount;
+
+ /**
+ * The number of method parameters that can have runtime invisible annotations. 0 means that all
+ * the parameters from the method descriptor can have annotations.
+ */
+ private int invisibleAnnotableParameterCount;
+
+ /** Whether the {@link #visitCode} method has been called. */
+ private boolean visitCodeCalled;
+
+ /** Whether the {@link #visitMaxs} method has been called. */
+ private boolean visitMaxCalled;
+
+ /** Whether the {@link #visitEnd} method has been called. */
+ private boolean visitEndCalled;
+
+ /** The number of visited instructions so far. */
+ private int insnCount;
+
+ /** The index of the instruction designated by each visited label. */
+ private final Map<Label, Integer> labelInsnIndices;
+
+ /** The labels referenced by the visited method. */
+ private Set<Label> referencedLabels;
+
+ /** The index of the instruction corresponding to the last visited stack map frame. */
+ private int lastFrameInsnIndex = -1;
+
+ /** The number of visited frames in expanded form. */
+ private int numExpandedFrames;
+
+ /** The number of visited frames in compressed form. */
+ private int numCompressedFrames;
+
+ /**
+ * The exception handler ranges. Each pair of list element contains the start and end labels of an
+ * exception handler block.
+ */
+ private List<Label> handlers;
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
+ * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
+ * <i>Subclasses must not use this constructor</i>. Instead, they must use the {@link
+ * #CheckMethodAdapter(int, MethodVisitor, Map)} version.
+ *
+ * @param methodvisitor the method visitor to which this adapter must delegate calls.
+ */
+ public CheckMethodAdapter(final MethodVisitor methodvisitor) {
+ this(methodvisitor, new HashMap<>());
+ }
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
+ * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
+ * <i>Subclasses must not use this constructor</i>. Instead, they must use the {@link
+ * #CheckMethodAdapter(int, MethodVisitor, Map)} version.
+ *
+ * @param methodVisitor the method visitor to which this adapter must delegate calls.
+ * @param labelInsnIndices the index of the instruction designated by each visited label so far
+ * (in other methods). This map is updated with the labels from the visited method.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public CheckMethodAdapter(
+ final MethodVisitor methodVisitor, final Map<Label, Integer> labelInsnIndices) {
+ this(/* latest api = */ Opcodes.ASM9, methodVisitor, labelInsnIndices);
+ if (getClass() != CheckMethodAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
+ * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
+ *
+ * @param api the ASM API version implemented by this CheckMethodAdapter. Must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to which this adapter must delegate calls.
+ * @param labelInsnIndices the index of the instruction designated by each visited label so far
+ * (in other methods). This map is updated with the labels from the visited method.
+ */
+ protected CheckMethodAdapter(
+ final int api,
+ final MethodVisitor methodVisitor,
+ final Map<Label, Integer> labelInsnIndices) {
+ super(api, methodVisitor);
+ this.labelInsnIndices = labelInsnIndices;
+ this.referencedLabels = new HashSet<>();
+ this.handlers = new ArrayList<>();
+ }
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object. This method adapter will perform basic data
+ * flow checks. For instance in a method whose signature is {@code void m ()}, the invalid
+ * instruction IRETURN, or the invalid sequence IADD L2I will be detected. <i>Subclasses must not
+ * use this constructor</i>. Instead, they must use the {@link
+ * #CheckMethodAdapter(int,int,String,String,MethodVisitor,Map)} version.
+ *
+ * @param access the method's access flags.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter must delegate calls.
+ * @param labelInsnIndices the index of the instruction designated by each visited label so far
+ * (in other methods). This map is updated with the labels from the visited method.
+ */
+ public CheckMethodAdapter(
+ final int access,
+ final String name,
+ final String descriptor,
+ final MethodVisitor methodVisitor,
+ final Map<Label, Integer> labelInsnIndices) {
+ this(
+ /* latest api = */ Opcodes.ASM9, access, name, descriptor, methodVisitor, labelInsnIndices);
+ if (getClass() != CheckMethodAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckMethodAdapter} object. This method adapter will perform basic data
+ * flow checks. For instance in a method whose signature is {@code void m ()}, the invalid
+ * instruction IRETURN, or the invalid sequence IADD L2I will be detected.
+ *
+ * @param api the ASM API version implemented by this CheckMethodAdapter. Must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ * @param access the method's access flags.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param methodVisitor the method visitor to which this adapter must delegate calls.
+ * @param labelInsnIndices the index of the instruction designated by each visited label so far
+ * (in other methods). This map is updated with the labels from the visited method.
+ */
+ protected CheckMethodAdapter(
+ final int api,
+ final int access,
+ final String name,
+ final String descriptor,
+ final MethodVisitor methodVisitor,
+ final Map<Label, Integer> labelInsnIndices) {
+ this(
+ api,
+ new MethodNode(api, access, name, descriptor, null, null) {
+ @Override
+ public void visitEnd() {
+ int originalMaxLocals = maxLocals;
+ int originalMaxStack = maxStack;
+ boolean checkMaxStackAndLocals = false;
+ boolean checkFrames = false;
+ if (methodVisitor instanceof MethodWriterWrapper) {
+ MethodWriterWrapper methodWriter = (MethodWriterWrapper) methodVisitor;
+ // If 'methodVisitor' is a MethodWriter of a ClassWriter with no flags to compute the
+ // max stack and locals nor the stack map frames, we know that valid max stack and
+ // locals must be provided. Otherwise we assume they are not needed at this stage.
+ checkMaxStackAndLocals = !methodWriter.computesMaxs();
+ // If 'methodVisitor' is a MethodWriter of a ClassWriter with no flags to compute the
+ // stack map frames, we know that valid frames must be provided. Otherwise we assume
+ // they are not needed at this stage.
+ checkFrames = methodWriter.requiresFrames() && !methodWriter.computesFrames();
+ }
+ Analyzer<BasicValue> analyzer =
+ checkFrames
+ ? new CheckFrameAnalyzer<>(new BasicVerifier())
+ : new Analyzer<>(new BasicVerifier());
+ try {
+ if (checkMaxStackAndLocals) {
+ analyzer.analyze("dummy", this);
+ } else {
+ analyzer.analyzeAndComputeMaxs("dummy", this);
+ }
+ } catch (IndexOutOfBoundsException | AnalyzerException e) {
+ throwError(analyzer, e);
+ }
+ if (methodVisitor != null) {
+ maxLocals = originalMaxLocals;
+ maxStack = originalMaxStack;
+ accept(methodVisitor);
+ }
+ }
+
+ private void throwError(final Analyzer<BasicValue> analyzer, final Exception e) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter, true);
+ CheckClassAdapter.printAnalyzerResult(this, analyzer, printWriter);
+ printWriter.close();
+ throw new IllegalArgumentException(e.getMessage() + ' ' + stringWriter.toString(), e);
+ }
+ },
+ labelInsnIndices);
+ this.access = access;
+ }
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ if (name != null) {
+ checkUnqualifiedName(version, name, "name");
+ }
+ CheckClassAdapter.checkAccess(
+ access, Opcodes.ACC_FINAL | Opcodes.ACC_MANDATED | Opcodes.ACC_SYNTHETIC);
+ super.visitParameter(name, access);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.METHOD_TYPE_PARAMETER
+ && sort != TypeReference.METHOD_TYPE_PARAMETER_BOUND
+ && sort != TypeReference.METHOD_RETURN
+ && sort != TypeReference.METHOD_RECEIVER
+ && sort != TypeReference.METHOD_FORMAL_PARAMETER
+ && sort != TypeReference.THROWS) {
+ throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ checkVisitEndNotCalled();
+ return new CheckAnnotationAdapter(super.visitAnnotationDefault(), false);
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ checkVisitEndNotCalled();
+ if (visible) {
+ visibleAnnotableParameterCount = parameterCount;
+ } else {
+ invisibleAnnotableParameterCount = parameterCount;
+ }
+ super.visitAnnotableParameterCount(parameterCount, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ if ((visible
+ && visibleAnnotableParameterCount > 0
+ && parameter >= visibleAnnotableParameterCount)
+ || (!visible
+ && invisibleAnnotableParameterCount > 0
+ && parameter >= invisibleAnnotableParameterCount)) {
+ throw new IllegalArgumentException("Invalid parameter index");
+ }
+ checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitParameterAnnotation(parameter, descriptor, visible));
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ checkVisitEndNotCalled();
+ if (attribute == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitCode() {
+ if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+ throw new UnsupportedOperationException("Abstract methods cannot have code");
+ }
+ visitCodeCalled = true;
+ super.visitCode();
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ if (insnCount == lastFrameInsnIndex) {
+ throw new IllegalStateException("At most one frame can be visited at a given code location.");
+ }
+ lastFrameInsnIndex = insnCount;
+ int maxNumLocal;
+ int maxNumStack;
+ switch (type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ maxNumLocal = Integer.MAX_VALUE;
+ maxNumStack = Integer.MAX_VALUE;
+ break;
+
+ case Opcodes.F_SAME:
+ maxNumLocal = 0;
+ maxNumStack = 0;
+ break;
+
+ case Opcodes.F_SAME1:
+ maxNumLocal = 0;
+ maxNumStack = 1;
+ break;
+
+ case Opcodes.F_APPEND:
+ case Opcodes.F_CHOP:
+ maxNumLocal = 3;
+ maxNumStack = 0;
+ break;
+
+ default:
+ throw new IllegalArgumentException("Invalid frame type " + type);
+ }
+
+ if (numLocal > maxNumLocal) {
+ throw new IllegalArgumentException(
+ "Invalid numLocal=" + numLocal + " for frame type " + type);
+ }
+ if (numStack > maxNumStack) {
+ throw new IllegalArgumentException(
+ "Invalid numStack=" + numStack + " for frame type " + type);
+ }
+
+ if (type != Opcodes.F_CHOP) {
+ if (numLocal > 0 && (local == null || local.length < numLocal)) {
+ throw new IllegalArgumentException("Array local[] is shorter than numLocal");
+ }
+ for (int i = 0; i < numLocal; ++i) {
+ checkFrameValue(local[i]);
+ }
+ }
+ if (numStack > 0 && (stack == null || stack.length < numStack)) {
+ throw new IllegalArgumentException("Array stack[] is shorter than numStack");
+ }
+ for (int i = 0; i < numStack; ++i) {
+ checkFrameValue(stack[i]);
+ }
+ if (type == Opcodes.F_NEW) {
+ ++numExpandedFrames;
+ } else {
+ ++numCompressedFrames;
+ }
+ if (numExpandedFrames > 0 && numCompressedFrames > 0) {
+ throw new IllegalArgumentException("Expanded and compressed frames must not be mixed.");
+ }
+ super.visitFrame(type, numLocal, local, numStack, stack);
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_INSN);
+ super.visitInsn(opcode);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_INT_INSN);
+ switch (opcode) {
+ case Opcodes.BIPUSH:
+ checkSignedByte(operand, "Invalid operand");
+ break;
+ case Opcodes.SIPUSH:
+ checkSignedShort(operand, "Invalid operand");
+ break;
+ case Opcodes.NEWARRAY:
+ if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
+ throw new IllegalArgumentException(
+ "Invalid operand (must be an array type code T_...): " + operand);
+ }
+ break;
+ default:
+ throw new AssertionError();
+ }
+ super.visitIntInsn(opcode, operand);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_VAR_INSN);
+ checkUnsignedShort(varIndex, INVALID_LOCAL_VARIABLE_INDEX);
+ super.visitVarInsn(opcode, varIndex);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_TYPE_INSN);
+ checkInternalName(version, type, "type");
+ if (opcode == Opcodes.NEW && type.charAt(0) == '[') {
+ throw new IllegalArgumentException("NEW cannot be used to create arrays: " + type);
+ }
+ super.visitTypeInsn(opcode, type);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_FIELD_INSN);
+ checkInternalName(version, owner, "owner");
+ checkUnqualifiedName(version, name, "name");
+ checkDescriptor(version, descriptor, false);
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;
+
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_METHOD_INSN);
+ if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
+ checkMethodIdentifier(version, name, "name");
+ }
+ checkInternalName(version, owner, "owner");
+ checkMethodDescriptor(version, descriptor);
+ if (opcode == Opcodes.INVOKEVIRTUAL && isInterface) {
+ throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
+ }
+ if (opcode == Opcodes.INVOKEINTERFACE && !isInterface) {
+ throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
+ }
+ if (opcode == Opcodes.INVOKESPECIAL && isInterface && (version & 0xFFFF) < Opcodes.V1_8) {
+ throw new IllegalArgumentException(
+ "INVOKESPECIAL can't be used with interfaces prior to Java 8");
+ }
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkMethodIdentifier(version, name, "name");
+ checkMethodDescriptor(version, descriptor);
+ if (bootstrapMethodHandle.getTag() != Opcodes.H_INVOKESTATIC
+ && bootstrapMethodHandle.getTag() != Opcodes.H_NEWINVOKESPECIAL) {
+ throw new IllegalArgumentException("invalid handle tag " + bootstrapMethodHandle.getTag());
+ }
+ for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
+ checkLdcConstant(bootstrapMethodArgument);
+ }
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkOpcodeMethod(opcode, Method.VISIT_JUMP_INSN);
+ checkLabel(label, /* checkVisited = */ false, "label");
+ super.visitJumpInsn(opcode, label);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkLabel(label, /* checkVisited = */ false, "label");
+ if (labelInsnIndices.get(label) != null) {
+ throw new IllegalStateException("Already visited label");
+ }
+ labelInsnIndices.put(label, insnCount);
+ super.visitLabel(label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkLdcConstant(value);
+ super.visitLdcInsn(value);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkUnsignedShort(varIndex, INVALID_LOCAL_VARIABLE_INDEX);
+ checkSignedShort(increment, "Invalid increment");
+ super.visitIincInsn(varIndex, increment);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ if (max < min) {
+ throw new IllegalArgumentException(
+ "Max = " + max + " must be greater than or equal to min = " + min);
+ }
+ checkLabel(dflt, /* checkVisited = */ false, "default label");
+ if (labels == null || labels.length != max - min + 1) {
+ throw new IllegalArgumentException("There must be max - min + 1 labels");
+ }
+ for (int i = 0; i < labels.length; ++i) {
+ checkLabel(labels[i], /* checkVisited = */ false, "label at index " + i);
+ }
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ checkVisitMaxsNotCalled();
+ checkVisitCodeCalled();
+ checkLabel(dflt, /* checkVisited = */ false, "default label");
+ if (keys == null || labels == null || keys.length != labels.length) {
+ throw new IllegalArgumentException("There must be the same number of keys and labels");
+ }
+ for (int i = 0; i < labels.length; ++i) {
+ checkLabel(labels[i], /* checkVisited = */ false, "label at index " + i);
+ }
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ ++insnCount;
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkDescriptor(version, descriptor, false);
+ if (descriptor.charAt(0) != '[') {
+ throw new IllegalArgumentException(
+ "Invalid descriptor (must be an array type descriptor): " + descriptor);
+ }
+ if (numDimensions < 1) {
+ throw new IllegalArgumentException(
+ "Invalid dimensions (must be greater than 0): " + numDimensions);
+ }
+ if (numDimensions > descriptor.lastIndexOf('[') + 1) {
+ throw new IllegalArgumentException(
+ "Invalid dimensions (must not be greater than numDimensions(descriptor)): "
+ + numDimensions);
+ }
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ ++insnCount;
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.INSTANCEOF
+ && sort != TypeReference.NEW
+ && sort != TypeReference.CONSTRUCTOR_REFERENCE
+ && sort != TypeReference.METHOD_REFERENCE
+ && sort != TypeReference.CAST
+ && sort != TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+ && sort != TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT
+ && sort != TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+ && sort != TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT) {
+ throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitInsnAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkLabel(start, /* checkVisited = */ false, START_LABEL);
+ checkLabel(end, /* checkVisited = */ false, END_LABEL);
+ checkLabel(handler, /* checkVisited = */ false, "handler label");
+ if (labelInsnIndices.get(start) != null
+ || labelInsnIndices.get(end) != null
+ || labelInsnIndices.get(handler) != null) {
+ throw new IllegalStateException("Try catch blocks must be visited before their labels");
+ }
+ if (type != null) {
+ checkInternalName(version, type, "type");
+ }
+ super.visitTryCatchBlock(start, end, handler, type);
+ handlers.add(start);
+ handlers.add(end);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.EXCEPTION_PARAMETER) {
+ throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(version, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkUnqualifiedName(version, name, "name");
+ checkDescriptor(version, descriptor, false);
+ if (signature != null) {
+ CheckClassAdapter.checkFieldSignature(signature);
+ }
+ checkLabel(start, /* checkVisited = */ true, START_LABEL);
+ checkLabel(end, /* checkVisited = */ true, END_LABEL);
+ checkUnsignedShort(index, INVALID_LOCAL_VARIABLE_INDEX);
+ int startInsnIndex = labelInsnIndices.get(start).intValue();
+ int endInsnIndex = labelInsnIndices.get(end).intValue();
+ if (endInsnIndex < startInsnIndex) {
+ throw new IllegalArgumentException(
+ "Invalid start and end labels (end must be greater than start)");
+ }
+ super.visitLocalVariable(name, descriptor, signature, start, end, index);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) {
+ throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ checkDescriptor(version, descriptor, false);
+ if (start == null
+ || end == null
+ || index == null
+ || end.length != start.length
+ || index.length != start.length) {
+ throw new IllegalArgumentException(
+ "Invalid start, end and index arrays (must be non null and of identical length");
+ }
+ for (int i = 0; i < start.length; ++i) {
+ checkLabel(start[i], /* checkVisited = */ true, START_LABEL);
+ checkLabel(end[i], /* checkVisited = */ true, END_LABEL);
+ checkUnsignedShort(index[i], INVALID_LOCAL_VARIABLE_INDEX);
+ int startInsnIndex = labelInsnIndices.get(start[i]).intValue();
+ int endInsnIndex = labelInsnIndices.get(end[i]).intValue();
+ if (endInsnIndex < startInsnIndex) {
+ throw new IllegalArgumentException(
+ "Invalid start and end labels (end must be greater than start)");
+ }
+ }
+ return super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible);
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ checkUnsignedShort(line, "Invalid line number");
+ checkLabel(start, /* checkVisited = */ true, START_LABEL);
+ super.visitLineNumber(line, start);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ checkVisitCodeCalled();
+ checkVisitMaxsNotCalled();
+ visitMaxCalled = true;
+ for (Label l : referencedLabels) {
+ if (labelInsnIndices.get(l) == null) {
+ throw new IllegalStateException("Undefined label used");
+ }
+ }
+ for (int i = 0; i < handlers.size(); i += 2) {
+ Integer startInsnIndex = labelInsnIndices.get(handlers.get(i));
+ Integer endInsnIndex = labelInsnIndices.get(handlers.get(i + 1));
+ if (endInsnIndex.intValue() <= startInsnIndex.intValue()) {
+ throw new IllegalStateException("Empty try catch block handler range");
+ }
+ }
+ checkUnsignedShort(maxStack, "Invalid max stack");
+ checkUnsignedShort(maxLocals, "Invalid max locals");
+ super.visitMaxs(maxStack, maxLocals);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkVisitEndNotCalled();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /** Checks that the {@link #visitCode} method has been called. */
+ private void checkVisitCodeCalled() {
+ if (!visitCodeCalled) {
+ throw new IllegalStateException(
+ "Cannot visit instructions before visitCode has been called.");
+ }
+ }
+
+ /** Checks that the {@link #visitMaxs} method has not been called. */
+ private void checkVisitMaxsNotCalled() {
+ if (visitMaxCalled) {
+ throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called.");
+ }
+ }
+
+ /** Checks that the {@link #visitEnd} method has not been called. */
+ private void checkVisitEndNotCalled() {
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot visit elements after visitEnd has been called.");
+ }
+ }
+
+ /**
+ * Checks a stack frame value.
+ *
+ * @param value the value to be checked.
+ */
+ private void checkFrameValue(final Object value) {
+ if (value == Opcodes.TOP
+ || value == Opcodes.INTEGER
+ || value == Opcodes.FLOAT
+ || value == Opcodes.LONG
+ || value == Opcodes.DOUBLE
+ || value == Opcodes.NULL
+ || value == Opcodes.UNINITIALIZED_THIS) {
+ return;
+ }
+ if (value instanceof String) {
+ checkInternalName(version, (String) value, "Invalid stack frame value");
+ } else if (value instanceof Label) {
+ checkLabel((Label) value, /* checkVisited = */ false, "label");
+ } else {
+ throw new IllegalArgumentException("Invalid stack frame value: " + value);
+ }
+ }
+
+ /**
+ * Checks that the method to visit the given opcode is equal to the given method.
+ *
+ * @param opcode the opcode to be checked.
+ * @param method the expected visit method.
+ */
+ private static void checkOpcodeMethod(final int opcode, final Method method) {
+ if (opcode < Opcodes.NOP || opcode > Opcodes.IFNONNULL || OPCODE_METHODS[opcode] != method) {
+ throw new IllegalArgumentException("Invalid opcode: " + opcode);
+ }
+ }
+
+ /**
+ * Checks that the given value is a signed byte.
+ *
+ * @param value the value to be checked.
+ * @param message the message to use in case of error.
+ */
+ private static void checkSignedByte(final int value, final String message) {
+ if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
+ throw new IllegalArgumentException(message + " (must be a signed byte): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is a signed short.
+ *
+ * @param value the value to be checked.
+ * @param message the message to use in case of error.
+ */
+ private static void checkSignedShort(final int value, final String message) {
+ if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
+ throw new IllegalArgumentException(message + " (must be a signed short): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is an unsigned short.
+ *
+ * @param value the value to be checked.
+ * @param message the message to use in case of error.
+ */
+ private static void checkUnsignedShort(final int value, final String message) {
+ if (value < 0 || value > 65535) {
+ throw new IllegalArgumentException(message + " (must be an unsigned short): " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is an {@link Integer}, {@link Float}, {@link Long}, {@link Double}
+ * or {@link String} value.
+ *
+ * @param value the value to be checked.
+ */
+ static void checkConstant(final Object value) {
+ if (!(value instanceof Integer)
+ && !(value instanceof Float)
+ && !(value instanceof Long)
+ && !(value instanceof Double)
+ && !(value instanceof String)) {
+ throw new IllegalArgumentException("Invalid constant: " + value);
+ }
+ }
+
+ /**
+ * Checks that the given value is a valid operand for the LDC instruction.
+ *
+ * @param value the value to be checked.
+ */
+ private void checkLdcConstant(final Object value) {
+ if (value instanceof Type) {
+ int sort = ((Type) value).getSort();
+ if (sort != Type.OBJECT && sort != Type.ARRAY && sort != Type.METHOD) {
+ throw new IllegalArgumentException("Illegal LDC constant value");
+ }
+ if (sort != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) {
+ throw new IllegalArgumentException("ldc of a constant class requires at least version 1.5");
+ }
+ if (sort == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) {
+ throw new IllegalArgumentException("ldc of a method type requires at least version 1.7");
+ }
+ } else if (value instanceof Handle) {
+ if ((version & 0xFFFF) < Opcodes.V1_7) {
+ throw new IllegalArgumentException("ldc of a Handle requires at least version 1.7");
+ }
+ Handle handle = (Handle) value;
+ int tag = handle.getTag();
+ if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) {
+ throw new IllegalArgumentException("invalid handle tag " + tag);
+ }
+ checkInternalName(this.version, handle.getOwner(), "handle owner");
+ if (tag <= Opcodes.H_PUTSTATIC) {
+ checkDescriptor(this.version, handle.getDesc(), false);
+ } else {
+ checkMethodDescriptor(this.version, handle.getDesc());
+ }
+ String handleName = handle.getName();
+ if (!("<init>".equals(handleName) && tag == Opcodes.H_NEWINVOKESPECIAL)) {
+ checkMethodIdentifier(this.version, handleName, "handle name");
+ }
+ } else if (value instanceof ConstantDynamic) {
+ if ((version & 0xFFFF) < Opcodes.V11) {
+ throw new IllegalArgumentException("ldc of a ConstantDynamic requires at least version 11");
+ }
+ ConstantDynamic constantDynamic = (ConstantDynamic) value;
+ checkMethodIdentifier(this.version, constantDynamic.getName(), "constant dynamic name");
+ checkDescriptor(this.version, constantDynamic.getDescriptor(), false);
+ checkLdcConstant(constantDynamic.getBootstrapMethod());
+ int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
+ for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
+ checkLdcConstant(constantDynamic.getBootstrapMethodArgument(i));
+ }
+ } else {
+ checkConstant(value);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid unqualified name.
+ *
+ * @param version the class version.
+ * @param name the string to be checked.
+ * @param message the message to use in case of error.
+ */
+ static void checkUnqualifiedName(final int version, final String name, final String message) {
+ checkIdentifier(version, name, 0, -1, message);
+ }
+
+ /**
+ * Checks that the given substring is a valid Java identifier.
+ *
+ * @param version the class version.
+ * @param name the string to be checked.
+ * @param startPos the index of the first character of the identifier (inclusive).
+ * @param endPos the index of the last character of the identifier (exclusive). -1 is equivalent
+ * to {@code name.length()} if name is not {@literal null}.
+ * @param message the message to use in case of error.
+ */
+ static void checkIdentifier(
+ final int version,
+ final String name,
+ final int startPos,
+ final int endPos,
+ final String message) {
+ if (name == null || (endPos == -1 ? name.length() <= startPos : endPos <= startPos)) {
+ throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
+ }
+ int max = endPos == -1 ? name.length() : endPos;
+ if ((version & 0xFFFF) >= Opcodes.V1_5) {
+ for (int i = startPos; i < max; i = name.offsetByCodePoints(i, 1)) {
+ if (".;[/".indexOf(name.codePointAt(i)) != -1) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must not contain . ; [ or /): " + name);
+ }
+ }
+ return;
+ }
+ for (int i = startPos; i < max; i = name.offsetByCodePoints(i, 1)) {
+ if (i == startPos
+ ? !Character.isJavaIdentifierStart(name.codePointAt(i))
+ : !Character.isJavaIdentifierPart(name.codePointAt(i))) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must be a valid Java identifier): " + name);
+ }
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid Java identifier.
+ *
+ * @param version the class version.
+ * @param name the string to be checked.
+ * @param message the message to use in case of error.
+ */
+ static void checkMethodIdentifier(final int version, final String name, final String message) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
+ }
+ if ((version & 0xFFFF) >= Opcodes.V1_5) {
+ for (int i = 0; i < name.length(); i = name.offsetByCodePoints(i, 1)) {
+ if (".;[/<>".indexOf(name.codePointAt(i)) != -1) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must be a valid unqualified name): " + name);
+ }
+ }
+ return;
+ }
+ for (int i = 0; i < name.length(); i = name.offsetByCodePoints(i, 1)) {
+ if (i == 0
+ ? !Character.isJavaIdentifierStart(name.codePointAt(i))
+ : !Character.isJavaIdentifierPart(name.codePointAt(i))) {
+ throw new IllegalArgumentException(
+ INVALID
+ + message
+ + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
+ + name);
+ }
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid internal class name or array type descriptor.
+ *
+ * @param version the class version.
+ * @param name the string to be checked.
+ * @param message the message to use in case of error.
+ */
+ static void checkInternalName(final int version, final String name, final String message) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
+ }
+ if (name.charAt(0) == '[') {
+ checkDescriptor(version, name, false);
+ } else {
+ checkInternalClassName(version, name, message);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid internal class name.
+ *
+ * @param version the class version.
+ * @param name the string to be checked.
+ * @param message the message to use in case of error.
+ */
+ private static void checkInternalClassName(
+ final int version, final String name, final String message) {
+ try {
+ int startIndex = 0;
+ int slashIndex;
+ while ((slashIndex = name.indexOf('/', startIndex + 1)) != -1) {
+ checkIdentifier(version, name, startIndex, slashIndex, null);
+ startIndex = slashIndex + 1;
+ }
+ checkIdentifier(version, name, startIndex, name.length(), null);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must be an internal class name): " + name, e);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid type descriptor.
+ *
+ * @param version the class version.
+ * @param descriptor the string to be checked.
+ * @param canBeVoid {@literal true} if {@code V} can be considered valid.
+ */
+ static void checkDescriptor(final int version, final String descriptor, final boolean canBeVoid) {
+ int endPos = checkDescriptor(version, descriptor, 0, canBeVoid);
+ if (endPos != descriptor.length()) {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ }
+
+ /**
+ * Checks that the given substring is a valid type descriptor.
+ *
+ * @param version the class version.
+ * @param descriptor the string to be checked.
+ * @param startPos the index of the first character of the type descriptor (inclusive).
+ * @param canBeVoid whether {@code V} can be considered valid.
+ * @return the index of the last character of the type descriptor, plus one.
+ */
+ private static int checkDescriptor(
+ final int version, final String descriptor, final int startPos, final boolean canBeVoid) {
+ if (descriptor == null || startPos >= descriptor.length()) {
+ throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)");
+ }
+ switch (descriptor.charAt(startPos)) {
+ case 'V':
+ if (canBeVoid) {
+ return startPos + 1;
+ } else {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ return startPos + 1;
+ case '[':
+ int pos = startPos + 1;
+ while (pos < descriptor.length() && descriptor.charAt(pos) == '[') {
+ ++pos;
+ }
+ if (pos < descriptor.length()) {
+ return checkDescriptor(version, descriptor, pos, false);
+ } else {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ case 'L':
+ int endPos = descriptor.indexOf(';', startPos);
+ if (startPos == -1 || endPos - startPos < 2) {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ try {
+ checkInternalClassName(version, descriptor.substring(startPos + 1, endPos), null);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor, e);
+ }
+ return endPos + 1;
+ default:
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ }
+
+ /**
+ * Checks that the given string is a valid method descriptor.
+ *
+ * @param version the class version.
+ * @param descriptor the string to be checked.
+ */
+ static void checkMethodDescriptor(final int version, final String descriptor) {
+ if (descriptor == null || descriptor.length() == 0) {
+ throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)");
+ }
+ if (descriptor.charAt(0) != '(' || descriptor.length() < 3) {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ int pos = 1;
+ if (descriptor.charAt(pos) != ')') {
+ do {
+ if (descriptor.charAt(pos) == 'V') {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ pos = checkDescriptor(version, descriptor, pos, false);
+ } while (pos < descriptor.length() && descriptor.charAt(pos) != ')');
+ }
+ pos = checkDescriptor(version, descriptor, pos + 1, true);
+ if (pos != descriptor.length()) {
+ throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
+ }
+ }
+
+ /**
+ * Checks that the given label is not null. This method can also check that the label has been
+ * visited.
+ *
+ * @param label the label to be checked.
+ * @param checkVisited whether to check that the label has been visited.
+ * @param message the message to use in case of error.
+ */
+ private void checkLabel(final Label label, final boolean checkVisited, final String message) {
+ if (label == null) {
+ throw new IllegalArgumentException(INVALID + message + " (must not be null)");
+ }
+ if (checkVisited && labelInsnIndices.get(label) == null) {
+ throw new IllegalArgumentException(INVALID + message + " (must be visited first)");
+ }
+ referencedLabels.add(label);
+ }
+
+ static class MethodWriterWrapper extends MethodVisitor {
+
+ /** The class version number. */
+ private final int version;
+
+ private final ClassWriter owner;
+
+ MethodWriterWrapper(
+ final int api,
+ final int version,
+ final ClassWriter owner,
+ final MethodVisitor methodWriter) {
+ super(api, methodWriter);
+ this.version = version;
+ this.owner = owner;
+ }
+
+ boolean computesMaxs() {
+ return owner.hasFlags(ClassWriter.COMPUTE_MAXS) || owner.hasFlags(ClassWriter.COMPUTE_FRAMES);
+ }
+
+ boolean computesFrames() {
+ return owner.hasFlags(ClassWriter.COMPUTE_FRAMES);
+ }
+
+ boolean requiresFrames() {
+ return (version & 0xFFFF) >= Opcodes.V1_7;
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java
new file mode 100644
index 00000000..bb748ae2
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java
@@ -0,0 +1,212 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.HashSet;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that checks that its methods are properly used.
+ *
+ * @author Remi Forax
+ */
+public class CheckModuleAdapter extends ModuleVisitor {
+ /** Whether the visited module is open. */
+ private final boolean isOpen;
+
+ /** The fully qualified names of the dependencies of the visited module. */
+ private final NameSet requiredModules = new NameSet("Modules requires");
+
+ /** The internal names of the packages exported by the visited module. */
+ private final NameSet exportedPackages = new NameSet("Module exports");
+
+ /** The internal names of the packages opened by the visited module. */
+ private final NameSet openedPackages = new NameSet("Module opens");
+
+ /** The internal names of the services used by the visited module. */
+ private final NameSet usedServices = new NameSet("Module uses");
+
+ /** The internal names of the services provided by the visited module. */
+ private final NameSet providedServices = new NameSet("Module provides");
+
+ /** The class version number. */
+ int classVersion;
+
+ /** Whether the {@link #visitEnd} method has been called. */
+ private boolean visitEndCalled;
+
+ /**
+ * Constructs a new {@link CheckModuleAdapter}. <i>Subclasses must not use this constructor</i>.
+ * Instead, they must use the {@link #CheckModuleAdapter(int, ModuleVisitor, boolean)} version.
+ *
+ * @param moduleVisitor the module visitor to which this adapter must delegate calls.
+ * @param isOpen whether the visited module is open. Open modules have their {@link
+ * Opcodes#ACC_OPEN} access flag set in {@link org.objectweb.asm.ClassVisitor#visitModule}.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public CheckModuleAdapter(final ModuleVisitor moduleVisitor, final boolean isOpen) {
+ this(/* latest api = */ Opcodes.ASM9, moduleVisitor, isOpen);
+ if (getClass() != CheckModuleAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckModuleAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param moduleVisitor the module visitor to which this adapter must delegate calls.
+ * @param isOpen whether the visited module is open. Open modules have their {@link
+ * Opcodes#ACC_OPEN} access flag set in {@link org.objectweb.asm.ClassVisitor#visitModule}.
+ */
+ protected CheckModuleAdapter(
+ final int api, final ModuleVisitor moduleVisitor, final boolean isOpen) {
+ super(api, moduleVisitor);
+ this.isOpen = isOpen;
+ }
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ // Modules can only appear in V9 or more classes.
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, mainClass, "module main class");
+ super.visitMainClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, packaze, "module package");
+ super.visitPackage(packaze);
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ checkVisitEndNotCalled();
+ CheckClassAdapter.checkFullyQualifiedName(Opcodes.V9, module, "required module");
+ requiredModules.checkNameNotAlreadyDeclared(module);
+ CheckClassAdapter.checkAccess(
+ access,
+ Opcodes.ACC_STATIC_PHASE
+ | Opcodes.ACC_TRANSITIVE
+ | Opcodes.ACC_SYNTHETIC
+ | Opcodes.ACC_MANDATED);
+ if (classVersion >= Opcodes.V10
+ && module.equals("java.base")
+ && (access & (Opcodes.ACC_STATIC_PHASE | Opcodes.ACC_TRANSITIVE)) != 0) {
+ throw new IllegalArgumentException(
+ "Invalid access flags: "
+ + access
+ + " java.base can not be declared ACC_TRANSITIVE or ACC_STATIC_PHASE");
+ }
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ checkVisitEndNotCalled();
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, packaze, "package name");
+ exportedPackages.checkNameNotAlreadyDeclared(packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (String module : modules) {
+ CheckClassAdapter.checkFullyQualifiedName(Opcodes.V9, module, "module export to");
+ }
+ }
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ checkVisitEndNotCalled();
+ if (isOpen) {
+ throw new UnsupportedOperationException("An open module can not use open directive");
+ }
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, packaze, "package name");
+ openedPackages.checkNameNotAlreadyDeclared(packaze);
+ CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_MANDATED);
+ if (modules != null) {
+ for (String module : modules) {
+ CheckClassAdapter.checkFullyQualifiedName(Opcodes.V9, module, "module open to");
+ }
+ }
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(final String service) {
+ checkVisitEndNotCalled();
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, service, "service");
+ usedServices.checkNameNotAlreadyDeclared(service);
+ super.visitUse(service);
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ checkVisitEndNotCalled();
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, service, "service");
+ providedServices.checkNameNotAlreadyDeclared(service);
+ if (providers == null || providers.length == 0) {
+ throw new IllegalArgumentException("Providers cannot be null or empty");
+ }
+ for (String provider : providers) {
+ CheckMethodAdapter.checkInternalName(Opcodes.V9, provider, "provider");
+ }
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkVisitEndNotCalled();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ private void checkVisitEndNotCalled() {
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+
+ private static class NameSet {
+
+ private final String type;
+ private final HashSet<String> names;
+
+ NameSet(final String type) {
+ this.type = type;
+ this.names = new HashSet<>();
+ }
+
+ void checkNameNotAlreadyDeclared(final String name) {
+ if (!names.add(name)) {
+ throw new IllegalArgumentException(type + " '" + name + "' already declared");
+ }
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckRecordComponentAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckRecordComponentAdapter.java
new file mode 100644
index 00000000..f6838778
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckRecordComponentAdapter.java
@@ -0,0 +1,121 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+
+/**
+ * A {@link RecordComponentVisitor} that checks that its methods are properly used.
+ *
+ * @author Eric Bruneton
+ * @author Remi Forax
+ */
+public class CheckRecordComponentAdapter extends RecordComponentVisitor {
+
+ /** Whether the {@link #visitEnd()} method has been called. */
+ private boolean visitEndCalled;
+
+ /**
+ * Constructs a new {@link CheckRecordComponentAdapter}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link #CheckRecordComponentAdapter(int,
+ * RecordComponentVisitor)} version.
+ *
+ * @param recordComponentVisitor the record component visitor to which this adapter must delegate
+ * calls.
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public CheckRecordComponentAdapter(final RecordComponentVisitor recordComponentVisitor) {
+ this(/* latest api =*/ Opcodes.ASM9, recordComponentVisitor);
+ if (getClass() != CheckRecordComponentAdapter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link CheckRecordComponentAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
+ * or {@link Opcodes#ASM9}.
+ * @param recordComponentVisitor the record component visitor to which this adapter must delegate
+ * calls.
+ */
+ protected CheckRecordComponentAdapter(
+ final int api, final RecordComponentVisitor recordComponentVisitor) {
+ super(api, recordComponentVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ // Annotations can only appear in V1_5 or more classes.
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ checkVisitEndNotCalled();
+ int sort = new TypeReference(typeRef).getSort();
+ if (sort != TypeReference.FIELD) {
+ throw new IllegalArgumentException(
+ "Invalid type reference sort 0x" + Integer.toHexString(sort));
+ }
+ CheckClassAdapter.checkTypeRef(typeRef);
+ CheckMethodAdapter.checkDescriptor(Opcodes.V1_5, descriptor, false);
+ return new CheckAnnotationAdapter(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ checkVisitEndNotCalled();
+ if (attribute == null) {
+ throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ }
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ checkVisitEndNotCalled();
+ visitEndCalled = true;
+ super.visitEnd();
+ }
+
+ private void checkVisitEndNotCalled() {
+ if (visitEndCalled) {
+ throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java
new file mode 100644
index 00000000..ed707b18
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java
@@ -0,0 +1,359 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.EnumSet;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+/**
+ * A {@link SignatureVisitor} that checks that its methods are properly used.
+ *
+ * @author Eric Bruneton
+ */
+public class CheckSignatureAdapter extends SignatureVisitor {
+
+ /**
+ * Type to be used to check class signatures. See {@link #CheckSignatureAdapter(int,
+ * SignatureVisitor)}.
+ */
+ public static final int CLASS_SIGNATURE = 0;
+
+ /**
+ * Type to be used to check method signatures. See {@link #CheckSignatureAdapter(int,
+ * SignatureVisitor)}.
+ */
+ public static final int METHOD_SIGNATURE = 1;
+
+ /**
+ * Type to be used to check type signatures.See {@link #CheckSignatureAdapter(int,
+ * SignatureVisitor)}.
+ */
+ public static final int TYPE_SIGNATURE = 2;
+
+ /** The valid automaton states for a {@link #visitFormalTypeParameter} method call. */
+ private static final EnumSet<State> VISIT_FORMAL_TYPE_PARAMETER_STATES =
+ EnumSet.of(State.EMPTY, State.FORMAL, State.BOUND);
+
+ /** The valid automaton states for a {@link #visitClassBound} method call. */
+ private static final EnumSet<State> VISIT_CLASS_BOUND_STATES = EnumSet.of(State.FORMAL);
+
+ /** The valid automaton states for a {@link #visitInterfaceBound} method call. */
+ private static final EnumSet<State> VISIT_INTERFACE_BOUND_STATES =
+ EnumSet.of(State.FORMAL, State.BOUND);
+
+ /** The valid automaton states for a {@link #visitSuperclass} method call. */
+ private static final EnumSet<State> VISIT_SUPER_CLASS_STATES =
+ EnumSet.of(State.EMPTY, State.FORMAL, State.BOUND);
+
+ /** The valid automaton states for a {@link #visitInterface} method call. */
+ private static final EnumSet<State> VISIT_INTERFACE_STATES = EnumSet.of(State.SUPER);
+
+ /** The valid automaton states for a {@link #visitParameterType} method call. */
+ private static final EnumSet<State> VISIT_PARAMETER_TYPE_STATES =
+ EnumSet.of(State.EMPTY, State.FORMAL, State.BOUND, State.PARAM);
+
+ /** The valid automaton states for a {@link #visitReturnType} method call. */
+ private static final EnumSet<State> VISIT_RETURN_TYPE_STATES =
+ EnumSet.of(State.EMPTY, State.FORMAL, State.BOUND, State.PARAM);
+
+ /** The valid automaton states for a {@link #visitExceptionType} method call. */
+ private static final EnumSet<State> VISIT_EXCEPTION_TYPE_STATES = EnumSet.of(State.RETURN);
+
+ /** The possible states of the automaton used to check the order of method calls. */
+ private enum State {
+ EMPTY,
+ FORMAL,
+ BOUND,
+ SUPER,
+ PARAM,
+ RETURN,
+ SIMPLE_TYPE,
+ CLASS_TYPE,
+ END;
+ }
+
+ private static final String INVALID = "Invalid ";
+
+ /** The type of the visited signature. */
+ private final int type;
+
+ /** The current state of the automaton used to check the order of method calls. */
+ private State state;
+
+ /** Whether the visited signature can be 'V'. */
+ private boolean canBeVoid;
+
+ /** The visitor to which this adapter must delegate calls. May be {@literal null}. */
+ private final SignatureVisitor signatureVisitor;
+
+ /**
+ * Constructs a new {@link CheckSignatureAdapter}. <i>Subclasses must not use this
+ * constructor</i>. Instead, they must use the {@link #CheckSignatureAdapter(int, int,
+ * SignatureVisitor)} version.
+ *
+ * @param type the type of signature to be checked. See {@link #CLASS_SIGNATURE}, {@link
+ * #METHOD_SIGNATURE} and {@link #TYPE_SIGNATURE}.
+ * @param signatureVisitor the visitor to which this adapter must delegate calls. May be {@literal
+ * null}.
+ */
+ public CheckSignatureAdapter(final int type, final SignatureVisitor signatureVisitor) {
+ this(/* latest api = */ Opcodes.ASM9, type, signatureVisitor);
+ }
+
+ /**
+ * Constructs a new {@link CheckSignatureAdapter}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param type the type of signature to be checked. See {@link #CLASS_SIGNATURE}, {@link
+ * #METHOD_SIGNATURE} and {@link #TYPE_SIGNATURE}.
+ * @param signatureVisitor the visitor to which this adapter must delegate calls. May be {@literal
+ * null}.
+ */
+ protected CheckSignatureAdapter(
+ final int api, final int type, final SignatureVisitor signatureVisitor) {
+ super(api);
+ this.type = type;
+ this.state = State.EMPTY;
+ this.signatureVisitor = signatureVisitor;
+ }
+
+ // class and method signatures
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ if (type == TYPE_SIGNATURE || !VISIT_FORMAL_TYPE_PARAMETER_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ checkIdentifier(name, "formal type parameter");
+ state = State.FORMAL;
+ if (signatureVisitor != null) {
+ signatureVisitor.visitFormalTypeParameter(name);
+ }
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ if (type == TYPE_SIGNATURE || !VISIT_CLASS_BOUND_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ state = State.BOUND;
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitClassBound());
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ if (type == TYPE_SIGNATURE || !VISIT_INTERFACE_BOUND_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitInterfaceBound());
+ }
+
+ // class signatures
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ if (type != CLASS_SIGNATURE || !VISIT_SUPER_CLASS_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ state = State.SUPER;
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitSuperclass());
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ if (type != CLASS_SIGNATURE || !VISIT_INTERFACE_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitInterface());
+ }
+
+ // method signatures
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ if (type != METHOD_SIGNATURE || !VISIT_PARAMETER_TYPE_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ state = State.PARAM;
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitParameterType());
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ if (type != METHOD_SIGNATURE || !VISIT_RETURN_TYPE_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ state = State.RETURN;
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitReturnType());
+ checkSignatureAdapter.canBeVoid = true;
+ return checkSignatureAdapter;
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ if (type != METHOD_SIGNATURE || !VISIT_EXCEPTION_TYPE_STATES.contains(state)) {
+ throw new IllegalStateException();
+ }
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitExceptionType());
+ }
+
+ // type signatures
+
+ @Override
+ public void visitBaseType(final char descriptor) {
+ if (type != TYPE_SIGNATURE || state != State.EMPTY) {
+ throw new IllegalStateException();
+ }
+ if (descriptor == 'V') {
+ if (!canBeVoid) {
+ throw new IllegalArgumentException("Base type descriptor can't be V");
+ }
+ } else {
+ if ("ZCBSIFJD".indexOf(descriptor) == -1) {
+ throw new IllegalArgumentException("Base type descriptor must be one of ZCBSIFJD");
+ }
+ }
+ state = State.SIMPLE_TYPE;
+ if (signatureVisitor != null) {
+ signatureVisitor.visitBaseType(descriptor);
+ }
+ }
+
+ @Override
+ public void visitTypeVariable(final String name) {
+ if (type != TYPE_SIGNATURE || state != State.EMPTY) {
+ throw new IllegalStateException();
+ }
+ checkIdentifier(name, "type variable");
+ state = State.SIMPLE_TYPE;
+ if (signatureVisitor != null) {
+ signatureVisitor.visitTypeVariable(name);
+ }
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ if (type != TYPE_SIGNATURE || state != State.EMPTY) {
+ throw new IllegalStateException();
+ }
+ state = State.SIMPLE_TYPE;
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE, signatureVisitor == null ? null : signatureVisitor.visitArrayType());
+ }
+
+ @Override
+ public void visitClassType(final String name) {
+ if (type != TYPE_SIGNATURE || state != State.EMPTY) {
+ throw new IllegalStateException();
+ }
+ checkClassName(name, "class name");
+ state = State.CLASS_TYPE;
+ if (signatureVisitor != null) {
+ signatureVisitor.visitClassType(name);
+ }
+ }
+
+ @Override
+ public void visitInnerClassType(final String name) {
+ if (state != State.CLASS_TYPE) {
+ throw new IllegalStateException();
+ }
+ checkIdentifier(name, "inner class name");
+ if (signatureVisitor != null) {
+ signatureVisitor.visitInnerClassType(name);
+ }
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ if (state != State.CLASS_TYPE) {
+ throw new IllegalStateException();
+ }
+ if (signatureVisitor != null) {
+ signatureVisitor.visitTypeArgument();
+ }
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(final char wildcard) {
+ if (state != State.CLASS_TYPE) {
+ throw new IllegalStateException();
+ }
+ if ("+-=".indexOf(wildcard) == -1) {
+ throw new IllegalArgumentException("Wildcard must be one of +-=");
+ }
+ return new CheckSignatureAdapter(
+ TYPE_SIGNATURE,
+ signatureVisitor == null ? null : signatureVisitor.visitTypeArgument(wildcard));
+ }
+
+ @Override
+ public void visitEnd() {
+ if (state != State.CLASS_TYPE) {
+ throw new IllegalStateException();
+ }
+ state = State.END;
+ if (signatureVisitor != null) {
+ signatureVisitor.visitEnd();
+ }
+ }
+
+ private void checkClassName(final String name, final String message) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException(INVALID + message + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must not contain . ; [ < > or :): " + name);
+ }
+ }
+ }
+
+ private void checkIdentifier(final String name, final String message) {
+ if (name == null || name.length() == 0) {
+ throw new IllegalArgumentException(INVALID + message + " (must not be null or empty)");
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (".;[/<>:".indexOf(name.charAt(i)) != -1) {
+ throw new IllegalArgumentException(
+ INVALID + message + " (must not contain . ; [ / < > or :): " + name);
+ }
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Printer.java b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java
new file mode 100644
index 00000000..f670dcc3
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java
@@ -0,0 +1,1310 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+
+/**
+ * An abstract converter from visit events to text.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class Printer {
+
+ /** The names of the Java Virtual Machine opcodes. */
+ public static final String[] OPCODES = {
+ "NOP", // 0 (0x0)
+ "ACONST_NULL", // 1 (0x1)
+ "ICONST_M1", // 2 (0x2)
+ "ICONST_0", // 3 (0x3)
+ "ICONST_1", // 4 (0x4)
+ "ICONST_2", // 5 (0x5)
+ "ICONST_3", // 6 (0x6)
+ "ICONST_4", // 7 (0x7)
+ "ICONST_5", // 8 (0x8)
+ "LCONST_0", // 9 (0x9)
+ "LCONST_1", // 10 (0xa)
+ "FCONST_0", // 11 (0xb)
+ "FCONST_1", // 12 (0xc)
+ "FCONST_2", // 13 (0xd)
+ "DCONST_0", // 14 (0xe)
+ "DCONST_1", // 15 (0xf)
+ "BIPUSH", // 16 (0x10)
+ "SIPUSH", // 17 (0x11)
+ "LDC", // 18 (0x12)
+ "LDC_W", // 19 (0x13)
+ "LDC2_W", // 20 (0x14)
+ "ILOAD", // 21 (0x15)
+ "LLOAD", // 22 (0x16)
+ "FLOAD", // 23 (0x17)
+ "DLOAD", // 24 (0x18)
+ "ALOAD", // 25 (0x19)
+ "ILOAD_0", // 26 (0x1a)
+ "ILOAD_1", // 27 (0x1b)
+ "ILOAD_2", // 28 (0x1c)
+ "ILOAD_3", // 29 (0x1d)
+ "LLOAD_0", // 30 (0x1e)
+ "LLOAD_1", // 31 (0x1f)
+ "LLOAD_2", // 32 (0x20)
+ "LLOAD_3", // 33 (0x21)
+ "FLOAD_0", // 34 (0x22)
+ "FLOAD_1", // 35 (0x23)
+ "FLOAD_2", // 36 (0x24)
+ "FLOAD_3", // 37 (0x25)
+ "DLOAD_0", // 38 (0x26)
+ "DLOAD_1", // 39 (0x27)
+ "DLOAD_2", // 40 (0x28)
+ "DLOAD_3", // 41 (0x29)
+ "ALOAD_0", // 42 (0x2a)
+ "ALOAD_1", // 43 (0x2b)
+ "ALOAD_2", // 44 (0x2c)
+ "ALOAD_3", // 45 (0x2d)
+ "IALOAD", // 46 (0x2e)
+ "LALOAD", // 47 (0x2f)
+ "FALOAD", // 48 (0x30)
+ "DALOAD", // 49 (0x31)
+ "AALOAD", // 50 (0x32)
+ "BALOAD", // 51 (0x33)
+ "CALOAD", // 52 (0x34)
+ "SALOAD", // 53 (0x35)
+ "ISTORE", // 54 (0x36)
+ "LSTORE", // 55 (0x37)
+ "FSTORE", // 56 (0x38)
+ "DSTORE", // 57 (0x39)
+ "ASTORE", // 58 (0x3a)
+ "ISTORE_0", // 59 (0x3b)
+ "ISTORE_1", // 60 (0x3c)
+ "ISTORE_2", // 61 (0x3d)
+ "ISTORE_3", // 62 (0x3e)
+ "LSTORE_0", // 63 (0x3f)
+ "LSTORE_1", // 64 (0x40)
+ "LSTORE_2", // 65 (0x41)
+ "LSTORE_3", // 66 (0x42)
+ "FSTORE_0", // 67 (0x43)
+ "FSTORE_1", // 68 (0x44)
+ "FSTORE_2", // 69 (0x45)
+ "FSTORE_3", // 70 (0x46)
+ "DSTORE_0", // 71 (0x47)
+ "DSTORE_1", // 72 (0x48)
+ "DSTORE_2", // 73 (0x49)
+ "DSTORE_3", // 74 (0x4a)
+ "ASTORE_0", // 75 (0x4b)
+ "ASTORE_1", // 76 (0x4c)
+ "ASTORE_2", // 77 (0x4d)
+ "ASTORE_3", // 78 (0x4e)
+ "IASTORE", // 79 (0x4f)
+ "LASTORE", // 80 (0x50)
+ "FASTORE", // 81 (0x51)
+ "DASTORE", // 82 (0x52)
+ "AASTORE", // 83 (0x53)
+ "BASTORE", // 84 (0x54)
+ "CASTORE", // 85 (0x55)
+ "SASTORE", // 86 (0x56)
+ "POP", // 87 (0x57)
+ "POP2", // 88 (0x58)
+ "DUP", // 89 (0x59)
+ "DUP_X1", // 90 (0x5a)
+ "DUP_X2", // 91 (0x5b)
+ "DUP2", // 92 (0x5c)
+ "DUP2_X1", // 93 (0x5d)
+ "DUP2_X2", // 94 (0x5e)
+ "SWAP", // 95 (0x5f)
+ "IADD", // 96 (0x60)
+ "LADD", // 97 (0x61)
+ "FADD", // 98 (0x62)
+ "DADD", // 99 (0x63)
+ "ISUB", // 100 (0x64)
+ "LSUB", // 101 (0x65)
+ "FSUB", // 102 (0x66)
+ "DSUB", // 103 (0x67)
+ "IMUL", // 104 (0x68)
+ "LMUL", // 105 (0x69)
+ "FMUL", // 106 (0x6a)
+ "DMUL", // 107 (0x6b)
+ "IDIV", // 108 (0x6c)
+ "LDIV", // 109 (0x6d)
+ "FDIV", // 110 (0x6e)
+ "DDIV", // 111 (0x6f)
+ "IREM", // 112 (0x70)
+ "LREM", // 113 (0x71)
+ "FREM", // 114 (0x72)
+ "DREM", // 115 (0x73)
+ "INEG", // 116 (0x74)
+ "LNEG", // 117 (0x75)
+ "FNEG", // 118 (0x76)
+ "DNEG", // 119 (0x77)
+ "ISHL", // 120 (0x78)
+ "LSHL", // 121 (0x79)
+ "ISHR", // 122 (0x7a)
+ "LSHR", // 123 (0x7b)
+ "IUSHR", // 124 (0x7c)
+ "LUSHR", // 125 (0x7d)
+ "IAND", // 126 (0x7e)
+ "LAND", // 127 (0x7f)
+ "IOR", // 128 (0x80)
+ "LOR", // 129 (0x81)
+ "IXOR", // 130 (0x82)
+ "LXOR", // 131 (0x83)
+ "IINC", // 132 (0x84)
+ "I2L", // 133 (0x85)
+ "I2F", // 134 (0x86)
+ "I2D", // 135 (0x87)
+ "L2I", // 136 (0x88)
+ "L2F", // 137 (0x89)
+ "L2D", // 138 (0x8a)
+ "F2I", // 139 (0x8b)
+ "F2L", // 140 (0x8c)
+ "F2D", // 141 (0x8d)
+ "D2I", // 142 (0x8e)
+ "D2L", // 143 (0x8f)
+ "D2F", // 144 (0x90)
+ "I2B", // 145 (0x91)
+ "I2C", // 146 (0x92)
+ "I2S", // 147 (0x93)
+ "LCMP", // 148 (0x94)
+ "FCMPL", // 149 (0x95)
+ "FCMPG", // 150 (0x96)
+ "DCMPL", // 151 (0x97)
+ "DCMPG", // 152 (0x98)
+ "IFEQ", // 153 (0x99)
+ "IFNE", // 154 (0x9a)
+ "IFLT", // 155 (0x9b)
+ "IFGE", // 156 (0x9c)
+ "IFGT", // 157 (0x9d)
+ "IFLE", // 158 (0x9e)
+ "IF_ICMPEQ", // 159 (0x9f)
+ "IF_ICMPNE", // 160 (0xa0)
+ "IF_ICMPLT", // 161 (0xa1)
+ "IF_ICMPGE", // 162 (0xa2)
+ "IF_ICMPGT", // 163 (0xa3)
+ "IF_ICMPLE", // 164 (0xa4)
+ "IF_ACMPEQ", // 165 (0xa5)
+ "IF_ACMPNE", // 166 (0xa6)
+ "GOTO", // 167 (0xa7)
+ "JSR", // 168 (0xa8)
+ "RET", // 169 (0xa9)
+ "TABLESWITCH", // 170 (0xaa)
+ "LOOKUPSWITCH", // 171 (0xab)
+ "IRETURN", // 172 (0xac)
+ "LRETURN", // 173 (0xad)
+ "FRETURN", // 174 (0xae)
+ "DRETURN", // 175 (0xaf)
+ "ARETURN", // 176 (0xb0)
+ "RETURN", // 177 (0xb1)
+ "GETSTATIC", // 178 (0xb2)
+ "PUTSTATIC", // 179 (0xb3)
+ "GETFIELD", // 180 (0xb4)
+ "PUTFIELD", // 181 (0xb5)
+ "INVOKEVIRTUAL", // 182 (0xb6)
+ "INVOKESPECIAL", // 183 (0xb7)
+ "INVOKESTATIC", // 184 (0xb8)
+ "INVOKEINTERFACE", // 185 (0xb9)
+ "INVOKEDYNAMIC", // 186 (0xba)
+ "NEW", // 187 (0xbb)
+ "NEWARRAY", // 188 (0xbc)
+ "ANEWARRAY", // 189 (0xbd)
+ "ARRAYLENGTH", // 190 (0xbe)
+ "ATHROW", // 191 (0xbf)
+ "CHECKCAST", // 192 (0xc0)
+ "INSTANCEOF", // 193 (0xc1)
+ "MONITORENTER", // 194 (0xc2)
+ "MONITOREXIT", // 195 (0xc3)
+ "WIDE", // 196 (0xc4)
+ "MULTIANEWARRAY", // 197 (0xc5)
+ "IFNULL", // 198 (0xc6)
+ "IFNONNULL" // 199 (0xc7)
+ };
+
+ /**
+ * The names of the {@code operand} values of the {@link
+ * org.objectweb.asm.MethodVisitor#visitIntInsn} method when {@code opcode} is {@code NEWARRAY}.
+ */
+ public static final String[] TYPES = {
+ "",
+ "",
+ "",
+ "",
+ "T_BOOLEAN",
+ "T_CHAR",
+ "T_FLOAT",
+ "T_DOUBLE",
+ "T_BYTE",
+ "T_SHORT",
+ "T_INT",
+ "T_LONG"
+ };
+
+ /** The names of the {@code tag} field values for {@link org.objectweb.asm.Handle}. */
+ public static final String[] HANDLE_TAG = {
+ "",
+ "H_GETFIELD",
+ "H_GETSTATIC",
+ "H_PUTFIELD",
+ "H_PUTSTATIC",
+ "H_INVOKEVIRTUAL",
+ "H_INVOKESTATIC",
+ "H_INVOKESPECIAL",
+ "H_NEWINVOKESPECIAL",
+ "H_INVOKEINTERFACE"
+ };
+
+ /** Message of the UnsupportedOperationException thrown by methods which must be overridden. */
+ private static final String UNSUPPORTED_OPERATION = "Must be overridden";
+
+ /**
+ * The ASM API version implemented by this class. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /** The builder used to build strings in the various visit methods. */
+ protected final StringBuilder stringBuilder;
+
+ /**
+ * The text to be printed. Since the code of methods is not necessarily visited in sequential
+ * order, one method after the other, but can be interlaced (some instructions from method one,
+ * then some instructions from method two, then some instructions from method one again...), it is
+ * not possible to print the visited instructions directly to a sequential stream. A class is
+ * therefore printed in a two steps process: a string tree is constructed during the visit, and
+ * printed to a sequential stream at the end of the visit. This string tree is stored in this
+ * field, as a string list that can contain other string lists, which can themselves contain other
+ * string lists, and so on.
+ */
+ public final List<Object> text;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link Printer}.
+ *
+ * @param api the ASM API version implemented by this printer. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected Printer(final int api) {
+ this.api = api;
+ this.stringBuilder = new StringBuilder();
+ this.text = new ArrayList<>();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Classes
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Class header. See {@link org.objectweb.asm.ClassVisitor#visit}.
+ *
+ * @param version the class version. The minor version is stored in the 16 most significant bits,
+ * and the major version in the 16 least significant bits.
+ * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the class is deprecated.
+ * @param name the internal name of the class (see {@link Type#getInternalName()}).
+ * @param signature the signature of this class. May be {@literal null} if the class is not a
+ * generic one, and does not extend or implement generic classes or interfaces.
+ * @param superName the internal of name of the super class (see {@link Type#getInternalName()}).
+ * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the
+ * {@link Object} class.
+ * @param interfaces the internal names of the class's interfaces (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ */
+ public abstract void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces);
+
+ /**
+ * Class source. See {@link org.objectweb.asm.ClassVisitor#visitSource}.
+ *
+ * @param source the name of the source file from which the class was compiled. May be {@literal
+ * null}.
+ * @param debug additional debug information to compute the correspondence between source and
+ * compiled elements of the class. May be {@literal null}.
+ */
+ public abstract void visitSource(String source, String debug);
+
+ /**
+ * Module. See {@link org.objectweb.asm.ClassVisitor#visitModule}.
+ *
+ * @param name the fully qualified name (using dots) of the module.
+ * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ * @param version the module version, or {@literal null}.
+ * @return the printer.
+ */
+ public Printer visitModule(final String name, final int access, final String version) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Visits the nest host class of the class. A nest is a set of classes of the same package that
+ * share access to their private members. One of these classes, called the host, lists the other
+ * members of the nest, which in turn should link to the host of their nest. This method must be
+ * called only once and only if the visited class is a non-host member of a nest. A class is
+ * implicitly its own nest, so it's invalid to call this method with the visited class name as
+ * argument.
+ *
+ * @param nestHost the internal name of the host class of the nest (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitNestHost(final String nestHost) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Class outer class. See {@link org.objectweb.asm.ClassVisitor#visitOuterClass}.
+ *
+ * @param owner internal name of the enclosing class of the class (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the method that contains the class, or {@literal null} if the class is
+ * not enclosed in a method of its enclosing class.
+ * @param descriptor the descriptor of the method that contains the class, or {@literal null} if
+ * the class is not enclosed in a method of its enclosing class.
+ */
+ public abstract void visitOuterClass(String owner, String name, String descriptor);
+
+ /**
+ * Class annotation. See {@link org.objectweb.asm.ClassVisitor#visitAnnotation}.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public abstract Printer visitClassAnnotation(String descriptor, boolean visible);
+
+ /**
+ * Class type annotation. See {@link org.objectweb.asm.ClassVisitor#visitTypeAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
+ * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitClassTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Class attribute. See {@link org.objectweb.asm.ClassVisitor#visitAttribute}.
+ *
+ * @param attribute an attribute.
+ */
+ public abstract void visitClassAttribute(Attribute attribute);
+
+ /**
+ * Visits a member of the nest. A nest is a set of classes of the same package that share access
+ * to their private members. One of these classes, called the host, lists the other members of the
+ * nest, which in turn should link to the host of their nest. This method must be called only if
+ * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so
+ * it's invalid to call this method with the visited class name as argument.
+ *
+ * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}).
+ */
+ public void visitNestMember(final String nestMember) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the
+ * current class. See {@link org.objectweb.asm.ClassVisitor#visitPermittedSubclass(String)}.
+ *
+ * @param permittedSubclass the internal name of a permitted subclass (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Class inner name. See {@link org.objectweb.asm.ClassVisitor#visitInnerClass}.
+ *
+ * @param name the internal name of an inner class (see {@link Type#getInternalName()}).
+ * @param outerName the internal name of the class to which the inner class belongs (see {@link
+ * Type#getInternalName()}). May be {@literal null} for not member classes.
+ * @param innerName the (simple) name of the inner class inside its enclosing class. May be
+ * {@literal null} for anonymous inner classes.
+ * @param access the access flags of the inner class as originally declared in the enclosing
+ * class.
+ */
+ public abstract void visitInnerClass(String name, String outerName, String innerName, int access);
+
+ /**
+ * Visits a record component of the class. See {@link
+ * org.objectweb.asm.ClassVisitor#visitRecordComponent(String, String, String)}.
+ *
+ * @param name the field's name.
+ * @param descriptor the record component descriptor (see {@link Type}).
+ * @param signature the record component signature. May be {@literal null} if the record component
+ * type does not use generic types.
+ * @return a visitor to visit this record component annotations and attributes, or {@literal null}
+ * if this class visitor is not interested in visiting these annotations and attributes.
+ */
+ public Printer visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Class field. See {@link org.objectweb.asm.ClassVisitor#visitField}.
+ *
+ * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the field is synthetic and/or deprecated.
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link Type}).
+ * @param signature the field's signature. May be {@literal null} if the field's type does not use
+ * generic types.
+ * @param value the field's initial value. This parameter, which may be {@literal null} if the
+ * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
+ * Long}, a {@link Double} or a {@link String} (for {@code int}, {@code float}, {@code long}
+ * or {@code String} fields respectively). <i>This parameter is only used for static
+ * fields</i>. Its value is ignored for non static fields, which must be initialized through
+ * bytecode instructions in constructors or methods.
+ * @return the printer.
+ */
+ public abstract Printer visitField(
+ int access, String name, String descriptor, String signature, Object value);
+
+ /**
+ * Class method. See {@link org.objectweb.asm.ClassVisitor#visitMethod}.
+ *
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param signature the method's signature. May be {@literal null} if the method parameters,
+ * return type and exceptions do not use generic types.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ * @return the printer.
+ */
+ public abstract Printer visitMethod(
+ int access, String name, String descriptor, String signature, String[] exceptions);
+
+ /** Class end. See {@link org.objectweb.asm.ClassVisitor#visitEnd}. */
+ public abstract void visitClassEnd();
+
+ // -----------------------------------------------------------------------------------------------
+ // Modules
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Module main class. See {@link org.objectweb.asm.ModuleVisitor#visitMainClass}.
+ *
+ * @param mainClass the internal name of the main class of the current module (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitMainClass(final String mainClass) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module package. See {@link org.objectweb.asm.ModuleVisitor#visitPackage}.
+ *
+ * @param packaze the internal name of a package (see {@link Type#getInternalName()}).
+ */
+ public void visitPackage(final String packaze) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module require. See {@link org.objectweb.asm.ModuleVisitor#visitRequire}.
+ *
+ * @param module the fully qualified name (using dots) of the dependence.
+ * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
+ * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param version the module version at compile time, or {@literal null}.
+ */
+ public void visitRequire(final String module, final int access, final String version) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module export. See {@link org.objectweb.asm.ModuleVisitor#visitExport}.
+ *
+ * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}).
+ * @param access the access flag of the exported package, valid values are among {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param modules the fully qualified names (using dots) of the modules that can access the public
+ * classes of the exported package, or {@literal null}.
+ */
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module open. See {@link org.objectweb.asm.ModuleVisitor#visitOpen}.
+ *
+ * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}).
+ * @param access the access flag of the opened package, valid values are among {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param modules the fully qualified names (using dots) of the modules that can use deep
+ * reflection to the classes of the open package, or {@literal null}.
+ */
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module use. See {@link org.objectweb.asm.ModuleVisitor#visitUse}.
+ *
+ * @param service the internal name of the service (see {@link Type#getInternalName()}).
+ */
+ public void visitUse(final String service) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Module provide. See {@link org.objectweb.asm.ModuleVisitor#visitProvide}.
+ *
+ * @param service the internal name of the service (see {@link Type#getInternalName()}).
+ * @param providers the internal names of the implementations of the service (there is at least
+ * one provider).
+ */
+ public void visitProvide(final String service, final String... providers) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /** Module end. See {@link org.objectweb.asm.ModuleVisitor#visitEnd}. */
+ public void visitModuleEnd() {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Annotations
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Annotation value. See {@link org.objectweb.asm.AnnotationVisitor#visit}.
+ *
+ * @param name the value name.
+ * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link
+ * Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+ * {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This
+ * value can also be an array of byte, boolean, short, char, int, long, float or double values
+ * (this is equivalent to using {@link #visitArray} and visiting each array element in turn,
+ * but is more convenient).
+ */
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ public abstract void visit(String name, Object value);
+
+ /**
+ * Annotation enum value. See {@link org.objectweb.asm.AnnotationVisitor#visitEnum}.
+ *
+ * @param name the value name.
+ * @param descriptor the class descriptor of the enumeration class.
+ * @param value the actual enumeration value.
+ */
+ public abstract void visitEnum(String name, String descriptor, String value);
+
+ /**
+ * Nested annotation value. See {@link org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
+ *
+ * @param name the value name.
+ * @param descriptor the class descriptor of the nested annotation class.
+ * @return the printer.
+ */
+ public abstract Printer visitAnnotation(String name, String descriptor);
+
+ /**
+ * Annotation array value. See {@link org.objectweb.asm.AnnotationVisitor#visitArray}.
+ *
+ * @param name the value name.
+ * @return the printer.
+ */
+ public abstract Printer visitArray(String name);
+
+ /** Annotation end. See {@link org.objectweb.asm.AnnotationVisitor#visitEnd}. */
+ public abstract void visitAnnotationEnd();
+
+ // -----------------------------------------------------------------------------------------------
+ // Record components
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits an annotation of the record component. See {@link
+ * org.objectweb.asm.RecordComponentVisitor#visitAnnotation}.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public Printer visitRecordComponentAnnotation(final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Visits an annotation on a type in the record component signature. See {@link
+ * org.objectweb.asm.RecordComponentVisitor#visitTypeAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
+ * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public Printer visitRecordComponentTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Visits a non standard attribute of the record component. See {@link
+ * org.objectweb.asm.RecordComponentVisitor#visitAttribute}.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitRecordComponentAttribute(final Attribute attribute) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Visits the end of the record component. See {@link
+ * org.objectweb.asm.RecordComponentVisitor#visitEnd}. This method, which is the last one to be
+ * called, is used to inform the visitor that everything have been visited.
+ */
+ public void visitRecordComponentEnd() {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Fields
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Field annotation. See {@link org.objectweb.asm.FieldVisitor#visitAnnotation}.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public abstract Printer visitFieldAnnotation(String descriptor, boolean visible);
+
+ /**
+ * Field type annotation. See {@link org.objectweb.asm.FieldVisitor#visitTypeAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#FIELD}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitFieldTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Field attribute. See {@link org.objectweb.asm.FieldVisitor#visitAttribute}.
+ *
+ * @param attribute an attribute.
+ */
+ public abstract void visitFieldAttribute(Attribute attribute);
+
+ /** Field end. See {@link org.objectweb.asm.FieldVisitor#visitEnd}. */
+ public abstract void visitFieldEnd();
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Method parameter. See {@link org.objectweb.asm.MethodVisitor#visitParameter(String, int)}.
+ *
+ * @param name parameter name or {@literal null} if none is provided.
+ * @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC}
+ * or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}).
+ */
+ public void visitParameter(final String name, final int access) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method default annotation. See {@link org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
+ *
+ * @return the printer.
+ */
+ public abstract Printer visitAnnotationDefault();
+
+ /**
+ * Method annotation. See {@link org.objectweb.asm.MethodVisitor#visitAnnotation}.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public abstract Printer visitMethodAnnotation(String descriptor, boolean visible);
+
+ /**
+ * Method type annotation. See {@link org.objectweb.asm.MethodVisitor#visitTypeAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#METHOD_TYPE_PARAMETER}, {@link
+ * TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link TypeReference#METHOD_RETURN}, {@link
+ * TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link
+ * TypeReference#THROWS}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitMethodTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Number of method parameters that can have annotations. See {@link
+ * org.objectweb.asm.MethodVisitor#visitAnnotableParameterCount}.
+ *
+ * @param parameterCount the number of method parameters than can have annotations. This number
+ * must be less or equal than the number of parameter types in the method descriptor. It can
+ * be strictly less when a method has synthetic parameters and when these parameters are
+ * ignored when computing parameter indices for the purpose of parameter annotations (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ * @param visible {@literal true} to define the number of method parameters that can have
+ * annotations visible at runtime, {@literal false} to define the number of method parameters
+ * that can have annotations invisible at runtime.
+ * @return the printer.
+ */
+ public Printer visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method parameter annotation. See {@link
+ * org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
+ *
+ * @param parameter the parameter index. This index must be strictly smaller than the number of
+ * parameters in the method descriptor, and strictly smaller than the parameter count
+ * specified in {@link #visitAnnotableParameterCount}. Important note: <i>a parameter index i
+ * is not required to correspond to the i'th parameter descriptor in the method
+ * descriptor</i>, in particular in case of synthetic parameters (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public abstract Printer visitParameterAnnotation(
+ int parameter, String descriptor, boolean visible);
+
+ /**
+ * Method attribute. See {@link org.objectweb.asm.MethodVisitor#visitAttribute}.
+ *
+ * @param attribute an attribute.
+ */
+ public abstract void visitMethodAttribute(Attribute attribute);
+
+ /** Method start. See {@link org.objectweb.asm.MethodVisitor#visitCode}. */
+ public abstract void visitCode();
+
+ /**
+ * Method stack frame. See {@link org.objectweb.asm.MethodVisitor#visitFrame}.
+ *
+ * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded
+ * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link
+ * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
+ * @param numLocal the number of local variables in the visited frame.
+ * @param local the local variable types in this frame. This array must not be modified. Primitive
+ * types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
+ * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element).
+ * Reference types are represented by String objects (representing internal names, see {@link
+ * Type#getInternalName()}), and uninitialized types by Label objects (this label designates
+ * the NEW instruction that created this uninitialized value).
+ * @param numStack the number of operand stack elements in the visited frame.
+ * @param stack the operand stack types in this frame. This array must not be modified. Its
+ * content has the same format as the "local" array.
+ */
+ public abstract void visitFrame(
+ int type, int numLocal, Object[] local, int numStack, Object[] stack);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitInsn}
+ *
+ * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
+ * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
+ * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
+ * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
+ * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
+ * SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
+ * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
+ * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
+ * D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
+ */
+ public abstract void visitInsn(int opcode);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitIntInsn}.
+ *
+ * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH
+ * or NEWARRAY.
+ * @param operand the operand of the instruction to be visited.<br>
+ * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.
+ * <br>
+ * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.
+ * <br>
+ * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link
+ * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE},
+ * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+ */
+ public abstract void visitIntInsn(int opcode, int operand);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitVarInsn}.
+ *
+ * @param opcode the opcode of the local variable instruction to be visited. This opcode is either
+ * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param varIndex the operand of the instruction to be visited. This operand is the index of a
+ * local variable.
+ */
+ public abstract void visitVarInsn(int opcode, int varIndex);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitTypeInsn}.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
+ * ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param type the operand of the instruction to be visited. This operand must be the internal
+ * name of an object or array class (see {@link Type#getInternalName()}).
+ */
+ public abstract void visitTypeInsn(int opcode, String type);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitFieldInsn}.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}).
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link Type}).
+ */
+ public abstract void visitFieldInsn(int opcode, String owner, String name, String descriptor);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ // This method was abstract before ASM5, and was therefore always overridden (without any
+ // call to 'super'). Thus, at this point we necessarily have api >= ASM5, and we must then
+ // redirect the method call to the ASM5 visitMethodInsn() method.
+ visitMethodInsn(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
+ }
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
+ * Type} or {@link Handle} value. This method is allowed to modify the content of the array so
+ * a caller should expect that this array may change.
+ */
+ public abstract void visitInvokeDynamicInsn(
+ String name,
+ String descriptor,
+ Handle bootstrapMethodHandle,
+ Object... bootstrapMethodArguments);
+
+ /**
+ * Method jump instruction. See {@link org.objectweb.asm.MethodVisitor#visitJumpInsn}.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
+ * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
+ * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label the operand of the instruction to be visited. This operand is a label that
+ * designates the instruction to which the jump instruction may jump.
+ */
+ public abstract void visitJumpInsn(int opcode, Label label);
+
+ /**
+ * Method label. See {@link org.objectweb.asm.MethodVisitor#visitLabel}.
+ *
+ * @param label a {@link Label} object.
+ */
+ public abstract void visitLabel(Label label);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitLdcInsn}.
+ *
+ * @param value the constant to be loaded on the stack. This parameter must be a non null {@link
+ * Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
+ * Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
+ * 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
+ * constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
+ * dynamic for classes whose version is 55.
+ */
+ public abstract void visitLdcInsn(Object value);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitIincInsn}.
+ *
+ * @param varIndex index of the local variable to be incremented.
+ * @param increment amount to increment the local variable by.
+ */
+ public abstract void visitIincInsn(int varIndex, int increment);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
+ *
+ * @param min the minimum key value.
+ * @param max the maximum key value.
+ * @param dflt beginning of the default handler block.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code min + i} key.
+ */
+ public abstract void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
+ *
+ * @param dflt beginning of the default handler block.
+ * @param keys the values of the keys.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code keys[i]} key.
+ */
+ public abstract void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);
+
+ /**
+ * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
+ *
+ * @param descriptor an array type descriptor (see {@link Type}).
+ * @param numDimensions the number of dimensions of the array to allocate.
+ */
+ public abstract void visitMultiANewArrayInsn(String descriptor, int numDimensions);
+
+ /**
+ * Instruction type annotation. See {@link org.objectweb.asm.MethodVisitor#visitInsnAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#INSTANCEOF}, {@link TypeReference#NEW}, {@link
+ * TypeReference#CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE}, {@link
+ * TypeReference#CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
+ * TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
+ * TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method exception handler. See {@link org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
+ *
+ * @param start the beginning of the exception handler's scope (inclusive).
+ * @param end the end of the exception handler's scope (exclusive).
+ * @param handler the beginning of the exception handler's code.
+ * @param type the internal name of the type of exceptions handled by the handler (see {@link
+ * Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally"
+ * blocks).
+ */
+ public abstract void visitTryCatchBlock(Label start, Label end, Label handler, String type);
+
+ /**
+ * Try catch block type annotation. See {@link
+ * org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method debug info. See {@link org.objectweb.asm.MethodVisitor#visitLocalVariable}.
+ *
+ * @param name the name of a local variable.
+ * @param descriptor the type descriptor of this local variable.
+ * @param signature the type signature of this local variable. May be {@literal null} if the local
+ * variable type does not use generic types.
+ * @param start the first instruction corresponding to the scope of this local variable
+ * (inclusive).
+ * @param end the last instruction corresponding to the scope of this local variable (exclusive).
+ * @param index the local variable's index.
+ */
+ public abstract void visitLocalVariable(
+ String name, String descriptor, String signature, Label start, Label end, int index);
+
+ /**
+ * Local variable type annotation. See {@link
+ * org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link
+ * TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param start the fist instructions corresponding to the continuous ranges that make the scope
+ * of this local variable (inclusive).
+ * @param end the last instructions corresponding to the continuous ranges that make the scope of
+ * this local variable (exclusive). This array must have the same size as the 'start' array.
+ * @param index the local variable's index in each range. This array must have the same size as
+ * the 'start' array.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return the printer.
+ */
+ public Printer visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
+ }
+
+ /**
+ * Method debug info. See {@link org.objectweb.asm.MethodVisitor#visitLineNumber}.
+ *
+ * @param line a line number. This number refers to the source file from which the class was
+ * compiled.
+ * @param start the first instruction corresponding to this line number.
+ */
+ public abstract void visitLineNumber(int line, Label start);
+
+ /**
+ * Method max stack and max locals. See {@link org.objectweb.asm.MethodVisitor#visitMaxs}.
+ *
+ * @param maxStack maximum stack size of the method.
+ * @param maxLocals maximum number of local variables for the method.
+ */
+ public abstract void visitMaxs(int maxStack, int maxLocals);
+
+ /** Method end. See {@link org.objectweb.asm.MethodVisitor#visitEnd}. */
+ public abstract void visitMethodEnd();
+
+ // -----------------------------------------------------------------------------------------------
+ // Print and utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the text constructed by this visitor.
+ *
+ * @return the text constructed by this visitor. See {@link #text}.
+ */
+ public List<Object> getText() {
+ return text;
+ }
+
+ /**
+ * Prints the text constructed by this visitor.
+ *
+ * @param printWriter the print writer to be used.
+ */
+ public void print(final PrintWriter printWriter) {
+ printList(printWriter, text);
+ }
+
+ /**
+ * Prints the given string tree.
+ *
+ * @param printWriter the writer to be used to print the tree.
+ * @param list a string tree, i.e., a string list that can contain other string lists, and so on
+ * recursively.
+ */
+ static void printList(final PrintWriter printWriter, final List<?> list) {
+ for (Object o : list) {
+ if (o instanceof List) {
+ printList(printWriter, (List<?>) o);
+ } else {
+ printWriter.print(o.toString());
+ }
+ }
+ }
+
+ /**
+ * Appends a quoted string to the given string builder.
+ *
+ * @param stringBuilder the buffer where the string must be added.
+ * @param string the string to be added.
+ */
+ public static void appendString(final StringBuilder stringBuilder, final String string) {
+ stringBuilder.append('\"');
+ for (int i = 0; i < string.length(); ++i) {
+ char c = string.charAt(i);
+ if (c == '\n') {
+ stringBuilder.append("\\n");
+ } else if (c == '\r') {
+ stringBuilder.append("\\r");
+ } else if (c == '\\') {
+ stringBuilder.append("\\\\");
+ } else if (c == '"') {
+ stringBuilder.append("\\\"");
+ } else if (c < 0x20 || c > 0x7f) {
+ stringBuilder.append("\\u");
+ if (c < 0x10) {
+ stringBuilder.append("000");
+ } else if (c < 0x100) {
+ stringBuilder.append("00");
+ } else if (c < 0x1000) {
+ stringBuilder.append('0');
+ }
+ stringBuilder.append(Integer.toString(c, 16));
+ } else {
+ stringBuilder.append(c);
+ }
+ }
+ stringBuilder.append('\"');
+ }
+
+ /**
+ * Prints the given class to the given output.
+ *
+ * <p>Command line arguments: [-nodebug] &lt;binary class name or class file name &gt;
+ *
+ * @param args the command line arguments.
+ * @param usage the help message to show when command line arguments are incorrect.
+ * @param printer the printer to convert the class into text.
+ * @param output where to print the result.
+ * @param logger where to log errors.
+ * @throws IOException if the class cannot be found, or if an IOException occurs.
+ */
+ static void main(
+ final String[] args,
+ final String usage,
+ final Printer printer,
+ final PrintWriter output,
+ final PrintWriter logger)
+ throws IOException {
+ if (args.length < 1
+ || args.length > 2
+ || ((args[0].equals("-debug") || args[0].equals("-nodebug")) && args.length != 2)) {
+ logger.println(usage);
+ return;
+ }
+
+ TraceClassVisitor traceClassVisitor = new TraceClassVisitor(null, printer, output);
+
+ String className;
+ int parsingOptions;
+ if (args[0].equals("-nodebug")) {
+ className = args[1];
+ parsingOptions = ClassReader.SKIP_DEBUG;
+ } else {
+ className = args[0];
+ parsingOptions = 0;
+ }
+
+ if (className.endsWith(".class")
+ || className.indexOf('\\') != -1
+ || className.indexOf('/') != -1) {
+ // Can't fix PMD warning for 1.5 compatibility.
+ try (InputStream inputStream = new FileInputStream(className)) { // NOPMD(AvoidFileStream)
+ new ClassReader(inputStream).accept(traceClassVisitor, parsingOptions);
+ }
+ } else {
+ new ClassReader(className).accept(traceClassVisitor, parsingOptions);
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java
new file mode 100644
index 00000000..0049d357
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java
@@ -0,0 +1,1604 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.signature.SignatureReader;
+
+/**
+ * A {@link Printer} that prints a disassembled view of the classes it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class Textifier extends Printer {
+
+ /** The help message shown when command line arguments are incorrect. */
+ private static final String USAGE =
+ "Prints a disassembled view of the given class.\n"
+ + "Usage: Textifier [-nodebug] <fully qualified class name or class file name>";
+
+ /**
+ * The type of internal names (see {@link Type#getInternalName()}). See {@link #appendDescriptor}.
+ */
+ public static final int INTERNAL_NAME = 0;
+
+ /** The type of field descriptors. See {@link #appendDescriptor}. */
+ public static final int FIELD_DESCRIPTOR = 1;
+
+ /** The type of field signatures. See {@link #appendDescriptor}. */
+ public static final int FIELD_SIGNATURE = 2;
+
+ /** The type of method descriptors. See {@link #appendDescriptor}. */
+ public static final int METHOD_DESCRIPTOR = 3;
+
+ /** The type of method signatures. See {@link #appendDescriptor}. */
+ public static final int METHOD_SIGNATURE = 4;
+
+ /** The type of class signatures. See {@link #appendDescriptor}. */
+ public static final int CLASS_SIGNATURE = 5;
+
+ /** The type of method handle descriptors. See {@link #appendDescriptor}. */
+ public static final int HANDLE_DESCRIPTOR = 9;
+
+ private static final String CLASS_SUFFIX = ".class";
+ private static final String DEPRECATED = "// DEPRECATED\n";
+ private static final String RECORD = "// RECORD\n";
+ private static final String INVISIBLE = " // invisible\n";
+
+ private static final List<String> FRAME_TYPES =
+ Collections.unmodifiableList(Arrays.asList("T", "I", "F", "D", "J", "N", "U"));
+
+ /** The indentation of class members at depth level 1 (e.g. fields, methods). */
+ protected String tab = " ";
+
+ /** The indentation of class elements at depth level 2 (e.g. bytecode instructions in methods). */
+ protected String tab2 = " ";
+
+ /** The indentation of class elements at depth level 3 (e.g. switch cases in methods). */
+ protected String tab3 = " ";
+
+ /** The indentation of labels. */
+ protected String ltab = " ";
+
+ /** The names of the labels. */
+ protected Map<Label, String> labelNames;
+
+ /** The access flags of the visited class. */
+ private int access;
+
+ /** The number of annotation values visited so far. */
+ private int numAnnotationValues;
+
+ /**
+ * Constructs a new {@link Textifier}. <i>Subclasses must not use this constructor</i>. Instead,
+ * they must use the {@link #Textifier(int)} version.
+ *
+ * @throws IllegalStateException If a subclass calls this constructor.
+ */
+ public Textifier() {
+ this(/* latest api = */ Opcodes.ASM9);
+ if (getClass() != Textifier.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Constructs a new {@link Textifier}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected Textifier(final int api) {
+ super(api);
+ }
+
+ /**
+ * Prints a disassembled view of the given class to the standard output.
+ *
+ * <p>Usage: Textifier [-nodebug] &lt;binary class name or class file name &gt;
+ *
+ * @param args the command line arguments.
+ * @throws IOException if the class cannot be found, or if an IOException occurs.
+ */
+ public static void main(final String[] args) throws IOException {
+ main(args, new PrintWriter(System.out, true), new PrintWriter(System.err, true));
+ }
+
+ /**
+ * Prints a disassembled view of the given class to the given output.
+ *
+ * <p>Usage: Textifier [-nodebug] &lt;binary class name or class file name &gt;
+ *
+ * @param args the command line arguments.
+ * @param output where to print the result.
+ * @param logger where to log errors.
+ * @throws IOException if the class cannot be found, or if an IOException occurs.
+ */
+ static void main(final String[] args, final PrintWriter output, final PrintWriter logger)
+ throws IOException {
+ main(args, USAGE, new Textifier(), output, logger);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Classes
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if ((access & Opcodes.ACC_MODULE) != 0) {
+ // Modules are printed in visitModule.
+ return;
+ }
+ this.access = access;
+ int majorVersion = version & 0xFFFF;
+ int minorVersion = version >>> 16;
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append("// class version ")
+ .append(majorVersion)
+ .append('.')
+ .append(minorVersion)
+ .append(" (")
+ .append(version)
+ .append(")\n");
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ stringBuilder.append(DEPRECATED);
+ }
+ if ((access & Opcodes.ACC_RECORD) != 0) {
+ stringBuilder.append(RECORD);
+ }
+ appendRawAccess(access);
+
+ appendDescriptor(CLASS_SIGNATURE, signature);
+ if (signature != null) {
+ appendJavaDeclaration(name, signature);
+ }
+
+ appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
+ if ((access & Opcodes.ACC_ANNOTATION) != 0) {
+ stringBuilder.append("@interface ");
+ } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
+ stringBuilder.append("interface ");
+ } else if ((access & Opcodes.ACC_ENUM) == 0) {
+ stringBuilder.append("class ");
+ }
+ appendDescriptor(INTERNAL_NAME, name);
+
+ if (superName != null && !"java/lang/Object".equals(superName)) {
+ stringBuilder.append(" extends ");
+ appendDescriptor(INTERNAL_NAME, superName);
+ }
+ if (interfaces != null && interfaces.length > 0) {
+ stringBuilder.append(" implements ");
+ for (int i = 0; i < interfaces.length; ++i) {
+ appendDescriptor(INTERNAL_NAME, interfaces[i]);
+ if (i != interfaces.length - 1) {
+ stringBuilder.append(' ');
+ }
+ }
+ }
+ stringBuilder.append(" {\n\n");
+
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitSource(final String file, final String debug) {
+ stringBuilder.setLength(0);
+ if (file != null) {
+ stringBuilder.append(tab).append("// compiled from: ").append(file).append('\n');
+ }
+ if (debug != null) {
+ stringBuilder.append(tab).append("// debug info: ").append(debug).append('\n');
+ }
+ if (stringBuilder.length() > 0) {
+ text.add(stringBuilder.toString());
+ }
+ }
+
+ @Override
+ public Printer visitModule(final String name, final int access, final String version) {
+ stringBuilder.setLength(0);
+ if ((access & Opcodes.ACC_OPEN) != 0) {
+ stringBuilder.append("open ");
+ }
+ stringBuilder
+ .append("module ")
+ .append(name)
+ .append(" { ")
+ .append(version == null ? "" : "// " + version)
+ .append("\n\n");
+ text.add(stringBuilder.toString());
+ return addNewTextifier(null);
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("NESTHOST ");
+ appendDescriptor(INTERNAL_NAME, nestHost);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("OUTERCLASS ");
+ appendDescriptor(INTERNAL_NAME, owner);
+ stringBuilder.append(' ');
+ if (name != null) {
+ stringBuilder.append(name).append(' ');
+ }
+ appendDescriptor(METHOD_DESCRIPTOR, descriptor);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Textifier visitClassAnnotation(final String descriptor, final boolean visible) {
+ text.add("\n");
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public Printer visitClassTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ text.add("\n");
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitClassAttribute(final Attribute attribute) {
+ text.add("\n");
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("NESTMEMBER ");
+ appendDescriptor(INTERNAL_NAME, nestMember);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("PERMITTEDSUBCLASS ");
+ appendDescriptor(INTERNAL_NAME, permittedSubclass);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab);
+ appendRawAccess(access & ~Opcodes.ACC_SUPER);
+ stringBuilder.append(tab);
+ appendAccess(access);
+ stringBuilder.append("INNERCLASS ");
+ appendDescriptor(INTERNAL_NAME, name);
+ stringBuilder.append(' ');
+ appendDescriptor(INTERNAL_NAME, outerName);
+ stringBuilder.append(' ');
+ appendDescriptor(INTERNAL_NAME, innerName);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("RECORDCOMPONENT ");
+ if (signature != null) {
+ stringBuilder.append(tab);
+ appendDescriptor(FIELD_SIGNATURE, signature);
+ stringBuilder.append(tab);
+ appendJavaDeclaration(name, signature);
+ }
+
+ stringBuilder.append(tab);
+
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append(' ').append(name);
+
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ return addNewTextifier(null);
+ }
+
+ @Override
+ public Textifier visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append('\n');
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ stringBuilder.append(tab).append(DEPRECATED);
+ }
+ stringBuilder.append(tab);
+ appendRawAccess(access);
+ if (signature != null) {
+ stringBuilder.append(tab);
+ appendDescriptor(FIELD_SIGNATURE, signature);
+ stringBuilder.append(tab);
+ appendJavaDeclaration(name, signature);
+ }
+
+ stringBuilder.append(tab);
+ appendAccess(access);
+
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append(' ').append(name);
+ if (value != null) {
+ stringBuilder.append(" = ");
+ if (value instanceof String) {
+ stringBuilder.append('\"').append(value).append('\"');
+ } else {
+ stringBuilder.append(value);
+ }
+ }
+
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ return addNewTextifier(null);
+ }
+
+ @Override
+ public Textifier visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ stringBuilder.setLength(0);
+ stringBuilder.append('\n');
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ stringBuilder.append(tab).append(DEPRECATED);
+ }
+ stringBuilder.append(tab);
+ appendRawAccess(access);
+
+ if (signature != null) {
+ stringBuilder.append(tab);
+ appendDescriptor(METHOD_SIGNATURE, signature);
+ stringBuilder.append(tab);
+ appendJavaDeclaration(name, signature);
+ }
+
+ stringBuilder.append(tab);
+ appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
+ if ((access & Opcodes.ACC_NATIVE) != 0) {
+ stringBuilder.append("native ");
+ }
+ if ((access & Opcodes.ACC_VARARGS) != 0) {
+ stringBuilder.append("varargs ");
+ }
+ if ((access & Opcodes.ACC_BRIDGE) != 0) {
+ stringBuilder.append("bridge ");
+ }
+ if ((this.access & Opcodes.ACC_INTERFACE) != 0
+ && (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC)) == 0) {
+ stringBuilder.append("default ");
+ }
+
+ stringBuilder.append(name);
+ appendDescriptor(METHOD_DESCRIPTOR, descriptor);
+ if (exceptions != null && exceptions.length > 0) {
+ stringBuilder.append(" throws ");
+ for (String exception : exceptions) {
+ appendDescriptor(INTERNAL_NAME, exception);
+ stringBuilder.append(' ');
+ }
+ }
+
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ return addNewTextifier(null);
+ }
+
+ @Override
+ public void visitClassEnd() {
+ text.add("}\n");
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Modules
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(" // main class ").append(mainClass).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(" // package ").append(packaze).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitRequire(final String require, final int access, final String version) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("requires ");
+ if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
+ stringBuilder.append("transitive ");
+ }
+ if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
+ stringBuilder.append("static ");
+ }
+ stringBuilder.append(require).append(';');
+ appendRawAccess(access);
+ if (version != null) {
+ stringBuilder.append(" // version ").append(version).append('\n');
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ visitExportOrOpen("exports ", packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ visitExportOrOpen("opens ", packaze, access, modules);
+ }
+
+ private void visitExportOrOpen(
+ final String method, final String packaze, final int access, final String... modules) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append(method);
+ stringBuilder.append(packaze);
+ if (modules != null && modules.length > 0) {
+ stringBuilder.append(" to");
+ } else {
+ stringBuilder.append(';');
+ }
+ appendRawAccess(access);
+ if (modules != null && modules.length > 0) {
+ for (int i = 0; i < modules.length; ++i) {
+ stringBuilder.append(tab2).append(modules[i]);
+ stringBuilder.append(i != modules.length - 1 ? ",\n" : ";\n");
+ }
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitUse(final String use) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("uses ");
+ appendDescriptor(INTERNAL_NAME, use);
+ stringBuilder.append(";\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitProvide(final String provide, final String... providers) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("provides ");
+ appendDescriptor(INTERNAL_NAME, provide);
+ stringBuilder.append(" with\n");
+ for (int i = 0; i < providers.length; ++i) {
+ stringBuilder.append(tab2);
+ appendDescriptor(INTERNAL_NAME, providers[i]);
+ stringBuilder.append(i != providers.length - 1 ? ",\n" : ";\n");
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitModuleEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Annotations
+ // -----------------------------------------------------------------------------------------------
+
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ @Override
+ public void visit(final String name, final Object value) {
+ visitAnnotationValue(name);
+ if (value instanceof String) {
+ visitString((String) value);
+ } else if (value instanceof Type) {
+ visitType((Type) value);
+ } else if (value instanceof Byte) {
+ visitByte(((Byte) value).byteValue());
+ } else if (value instanceof Boolean) {
+ visitBoolean(((Boolean) value).booleanValue());
+ } else if (value instanceof Short) {
+ visitShort(((Short) value).shortValue());
+ } else if (value instanceof Character) {
+ visitChar(((Character) value).charValue());
+ } else if (value instanceof Integer) {
+ visitInt(((Integer) value).intValue());
+ } else if (value instanceof Float) {
+ visitFloat(((Float) value).floatValue());
+ } else if (value instanceof Long) {
+ visitLong(((Long) value).longValue());
+ } else if (value instanceof Double) {
+ visitDouble(((Double) value).doubleValue());
+ } else if (value.getClass().isArray()) {
+ stringBuilder.append('{');
+ if (value instanceof byte[]) {
+ byte[] byteArray = (byte[]) value;
+ for (int i = 0; i < byteArray.length; i++) {
+ maybeAppendComma(i);
+ visitByte(byteArray[i]);
+ }
+ } else if (value instanceof boolean[]) {
+ boolean[] booleanArray = (boolean[]) value;
+ for (int i = 0; i < booleanArray.length; i++) {
+ maybeAppendComma(i);
+ visitBoolean(booleanArray[i]);
+ }
+ } else if (value instanceof short[]) {
+ short[] shortArray = (short[]) value;
+ for (int i = 0; i < shortArray.length; i++) {
+ maybeAppendComma(i);
+ visitShort(shortArray[i]);
+ }
+ } else if (value instanceof char[]) {
+ char[] charArray = (char[]) value;
+ for (int i = 0; i < charArray.length; i++) {
+ maybeAppendComma(i);
+ visitChar(charArray[i]);
+ }
+ } else if (value instanceof int[]) {
+ int[] intArray = (int[]) value;
+ for (int i = 0; i < intArray.length; i++) {
+ maybeAppendComma(i);
+ visitInt(intArray[i]);
+ }
+ } else if (value instanceof long[]) {
+ long[] longArray = (long[]) value;
+ for (int i = 0; i < longArray.length; i++) {
+ maybeAppendComma(i);
+ visitLong(longArray[i]);
+ }
+ } else if (value instanceof float[]) {
+ float[] floatArray = (float[]) value;
+ for (int i = 0; i < floatArray.length; i++) {
+ maybeAppendComma(i);
+ visitFloat(floatArray[i]);
+ }
+ } else if (value instanceof double[]) {
+ double[] doubleArray = (double[]) value;
+ for (int i = 0; i < doubleArray.length; i++) {
+ maybeAppendComma(i);
+ visitDouble(doubleArray[i]);
+ }
+ }
+ stringBuilder.append('}');
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ private void visitInt(final int value) {
+ stringBuilder.append(value);
+ }
+
+ private void visitLong(final long value) {
+ stringBuilder.append(value).append('L');
+ }
+
+ private void visitFloat(final float value) {
+ stringBuilder.append(value).append('F');
+ }
+
+ private void visitDouble(final double value) {
+ stringBuilder.append(value).append('D');
+ }
+
+ private void visitChar(final char value) {
+ stringBuilder.append("(char)").append((int) value);
+ }
+
+ private void visitShort(final short value) {
+ stringBuilder.append("(short)").append(value);
+ }
+
+ private void visitByte(final byte value) {
+ stringBuilder.append("(byte)").append(value);
+ }
+
+ private void visitBoolean(final boolean value) {
+ stringBuilder.append(value);
+ }
+
+ private void visitString(final String value) {
+ appendString(stringBuilder, value);
+ }
+
+ private void visitType(final Type value) {
+ stringBuilder.append(value.getClassName()).append(CLASS_SUFFIX);
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ visitAnnotationValue(name);
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('.').append(value);
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Textifier visitAnnotation(final String name, final String descriptor) {
+ visitAnnotationValue(name);
+ stringBuilder.append('@');
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+ return addNewTextifier(")");
+ }
+
+ @Override
+ public Textifier visitArray(final String name) {
+ visitAnnotationValue(name);
+ stringBuilder.append('{');
+ text.add(stringBuilder.toString());
+ return addNewTextifier("}");
+ }
+
+ @Override
+ public void visitAnnotationEnd() {
+ // Nothing to do.
+ }
+
+ private void visitAnnotationValue(final String name) {
+ stringBuilder.setLength(0);
+ maybeAppendComma(numAnnotationValues++);
+ if (name != null) {
+ stringBuilder.append(name).append('=');
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Record components
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public Textifier visitRecordComponentAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public Printer visitRecordComponentTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitRecordComponentAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitRecordComponentEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Fields
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public Textifier visitFieldAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public Printer visitFieldTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitFieldAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitFieldEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("// parameter ");
+ appendAccess(access);
+ stringBuilder.append(' ').append((name == null) ? "<no name>" : name).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Textifier visitAnnotationDefault() {
+ text.add(tab2 + "default=");
+ return addNewTextifier("\n");
+ }
+
+ @Override
+ public Textifier visitMethodAnnotation(final String descriptor, final boolean visible) {
+ return visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public Printer visitMethodTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public Textifier visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("// annotable parameter count: ");
+ stringBuilder.append(parameterCount);
+ stringBuilder.append(visible ? " (visible)\n" : " (invisible)\n");
+ text.add(stringBuilder.toString());
+ return this;
+ }
+
+ @Override
+ public Textifier visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append('@');
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(visible ? ") // parameter " : ") // invisible, parameter ")
+ .append(parameter)
+ .append('\n');
+ return addNewTextifier(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMethodAttribute(final Attribute attribute) {
+ visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitCode() {
+ // Nothing to do.
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(ltab);
+ stringBuilder.append("FRAME ");
+ switch (type) {
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ stringBuilder.append("FULL [");
+ appendFrameTypes(numLocal, local);
+ stringBuilder.append("] [");
+ appendFrameTypes(numStack, stack);
+ stringBuilder.append(']');
+ break;
+ case Opcodes.F_APPEND:
+ stringBuilder.append("APPEND [");
+ appendFrameTypes(numLocal, local);
+ stringBuilder.append(']');
+ break;
+ case Opcodes.F_CHOP:
+ stringBuilder.append("CHOP ").append(numLocal);
+ break;
+ case Opcodes.F_SAME:
+ stringBuilder.append("SAME");
+ break;
+ case Opcodes.F_SAME1:
+ stringBuilder.append("SAME1 ");
+ appendFrameTypes(1, stack);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(tab2)
+ .append(OPCODES[opcode])
+ .append(' ')
+ .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer.toString(operand))
+ .append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append(' ').append(varIndex).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append(' ');
+ appendDescriptor(INTERNAL_NAME, type);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append(' ');
+ appendDescriptor(INTERNAL_NAME, owner);
+ stringBuilder.append('.').append(name).append(" : ");
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append(' ');
+ appendDescriptor(INTERNAL_NAME, owner);
+ stringBuilder.append('.').append(name).append(' ');
+ appendDescriptor(METHOD_DESCRIPTOR, descriptor);
+ if (isInterface) {
+ stringBuilder.append(" (itf)");
+ }
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("INVOKEDYNAMIC").append(' ');
+ stringBuilder.append(name);
+ appendDescriptor(METHOD_DESCRIPTOR, descriptor);
+ stringBuilder.append(" [");
+ stringBuilder.append('\n');
+ stringBuilder.append(tab3);
+ appendHandle(bootstrapMethodHandle);
+ stringBuilder.append('\n');
+ stringBuilder.append(tab3).append("// arguments:");
+ if (bootstrapMethodArguments.length == 0) {
+ stringBuilder.append(" none");
+ } else {
+ stringBuilder.append('\n');
+ for (Object value : bootstrapMethodArguments) {
+ stringBuilder.append(tab3);
+ if (value instanceof String) {
+ Printer.appendString(stringBuilder, (String) value);
+ } else if (value instanceof Type) {
+ Type type = (Type) value;
+ if (type.getSort() == Type.METHOD) {
+ appendDescriptor(METHOD_DESCRIPTOR, type.getDescriptor());
+ } else {
+ visitType(type);
+ }
+ } else if (value instanceof Handle) {
+ appendHandle((Handle) value);
+ } else {
+ stringBuilder.append(value);
+ }
+ stringBuilder.append(", \n");
+ }
+ stringBuilder.setLength(stringBuilder.length() - 3);
+ }
+ stringBuilder.append('\n');
+ stringBuilder.append(tab2).append("]\n");
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append(OPCODES[opcode]).append(' ');
+ appendLabel(label);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(ltab);
+ appendLabel(label);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("LDC ");
+ if (value instanceof String) {
+ Printer.appendString(stringBuilder, (String) value);
+ } else if (value instanceof Type) {
+ stringBuilder.append(((Type) value).getDescriptor()).append(CLASS_SUFFIX);
+ } else {
+ stringBuilder.append(value);
+ }
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ stringBuilder.setLength(0);
+ stringBuilder
+ .append(tab2)
+ .append("IINC ")
+ .append(varIndex)
+ .append(' ')
+ .append(increment)
+ .append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("TABLESWITCH\n");
+ for (int i = 0; i < labels.length; ++i) {
+ stringBuilder.append(tab3).append(min + i).append(": ");
+ appendLabel(labels[i]);
+ stringBuilder.append('\n');
+ }
+ stringBuilder.append(tab3).append("default: ");
+ appendLabel(dflt);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("LOOKUPSWITCH\n");
+ for (int i = 0; i < labels.length; ++i) {
+ stringBuilder.append(tab3).append(keys[i]).append(": ");
+ appendLabel(labels[i]);
+ stringBuilder.append('\n');
+ }
+ stringBuilder.append(tab3).append("default: ");
+ appendLabel(dflt);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("MULTIANEWARRAY ");
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append(' ').append(numDimensions).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ return visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("TRYCATCHBLOCK ");
+ appendLabel(start);
+ stringBuilder.append(' ');
+ appendLabel(end);
+ stringBuilder.append(' ');
+ appendLabel(handler);
+ stringBuilder.append(' ');
+ appendDescriptor(INTERNAL_NAME, type);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("TRYCATCHBLOCK @");
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+
+ stringBuilder.setLength(0);
+ stringBuilder.append(") : ");
+ appendTypeReference(typeRef);
+ stringBuilder.append(", ").append(typePath);
+ stringBuilder.append(visible ? "\n" : INVISIBLE);
+ return addNewTextifier(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append(' ');
+ appendLabel(start);
+ stringBuilder.append(' ');
+ appendLabel(end);
+ stringBuilder.append(' ').append(index).append('\n');
+
+ if (signature != null) {
+ stringBuilder.append(tab2);
+ appendDescriptor(FIELD_SIGNATURE, signature);
+ stringBuilder.append(tab2);
+ appendJavaDeclaration(name, signature);
+ }
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public Printer visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("LOCALVARIABLE @");
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+
+ stringBuilder.setLength(0);
+ stringBuilder.append(") : ");
+ appendTypeReference(typeRef);
+ stringBuilder.append(", ").append(typePath);
+ for (int i = 0; i < start.length; ++i) {
+ stringBuilder.append(" [ ");
+ appendLabel(start[i]);
+ stringBuilder.append(" - ");
+ appendLabel(end[i]);
+ stringBuilder.append(" - ").append(index[i]).append(" ]");
+ }
+ stringBuilder.append(visible ? "\n" : INVISIBLE);
+ return addNewTextifier(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("LINENUMBER ").append(line).append(' ');
+ appendLabel(start);
+ stringBuilder.append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("MAXSTACK = ").append(maxStack).append('\n');
+ text.add(stringBuilder.toString());
+
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab2).append("MAXLOCALS = ").append(maxLocals).append('\n');
+ text.add(stringBuilder.toString());
+ }
+
+ @Override
+ public void visitMethodEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Common methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Prints a disassembled view of the given annotation.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values.
+ */
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ public Textifier visitAnnotation(final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append('@');
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+ return addNewTextifier(visible ? ")\n" : ") // invisible\n");
+ }
+
+ /**
+ * Prints a disassembled view of the given type annotation.
+ *
+ * @param typeRef a reference to the annotated type. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values.
+ */
+ public Textifier visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append('@');
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ stringBuilder.append('(');
+ text.add(stringBuilder.toString());
+
+ stringBuilder.setLength(0);
+ stringBuilder.append(") : ");
+ appendTypeReference(typeRef);
+ stringBuilder.append(", ").append(typePath);
+ stringBuilder.append(visible ? "\n" : INVISIBLE);
+ return addNewTextifier(stringBuilder.toString());
+ }
+
+ /**
+ * Prints a disassembled view of the given attribute.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ stringBuilder.setLength(0);
+ stringBuilder.append(tab).append("ATTRIBUTE ");
+ appendDescriptor(-1, attribute.type);
+
+ if (attribute instanceof TextifierSupport) {
+ if (labelNames == null) {
+ labelNames = new HashMap<>();
+ }
+ ((TextifierSupport) attribute).textify(stringBuilder, labelNames);
+ } else {
+ stringBuilder.append(" : unknown\n");
+ }
+
+ text.add(stringBuilder.toString());
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Appends a string representation of the given access flags to {@link #stringBuilder}.
+ *
+ * @param accessFlags some access flags.
+ */
+ private void appendAccess(final int accessFlags) {
+ if ((accessFlags & Opcodes.ACC_PUBLIC) != 0) {
+ stringBuilder.append("public ");
+ }
+ if ((accessFlags & Opcodes.ACC_PRIVATE) != 0) {
+ stringBuilder.append("private ");
+ }
+ if ((accessFlags & Opcodes.ACC_PROTECTED) != 0) {
+ stringBuilder.append("protected ");
+ }
+ if ((accessFlags & Opcodes.ACC_FINAL) != 0) {
+ stringBuilder.append("final ");
+ }
+ if ((accessFlags & Opcodes.ACC_STATIC) != 0) {
+ stringBuilder.append("static ");
+ }
+ if ((accessFlags & Opcodes.ACC_SYNCHRONIZED) != 0) {
+ stringBuilder.append("synchronized ");
+ }
+ if ((accessFlags & Opcodes.ACC_VOLATILE) != 0) {
+ stringBuilder.append("volatile ");
+ }
+ if ((accessFlags & Opcodes.ACC_TRANSIENT) != 0) {
+ stringBuilder.append("transient ");
+ }
+ if ((accessFlags & Opcodes.ACC_ABSTRACT) != 0) {
+ stringBuilder.append("abstract ");
+ }
+ if ((accessFlags & Opcodes.ACC_STRICT) != 0) {
+ stringBuilder.append("strictfp ");
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0) {
+ stringBuilder.append("synthetic ");
+ }
+ if ((accessFlags & Opcodes.ACC_MANDATED) != 0) {
+ stringBuilder.append("mandated ");
+ }
+ if ((accessFlags & Opcodes.ACC_ENUM) != 0) {
+ stringBuilder.append("enum ");
+ }
+ }
+
+ /**
+ * Appends the hexadecimal value of the given access flags to {@link #stringBuilder}.
+ *
+ * @param accessFlags some access flags.
+ */
+ private void appendRawAccess(final int accessFlags) {
+ stringBuilder
+ .append("// access flags 0x")
+ .append(Integer.toHexString(accessFlags).toUpperCase())
+ .append('\n');
+ }
+
+ /**
+ * Appends an internal name, a type descriptor or a type signature to {@link #stringBuilder}.
+ *
+ * @param type the type of 'value'. Must be one of {@link #INTERNAL_NAME}, {@link
+ * #FIELD_DESCRIPTOR}, {@link #FIELD_SIGNATURE}, {@link #METHOD_DESCRIPTOR}, {@link
+ * #METHOD_SIGNATURE}, {@link #CLASS_SIGNATURE} or {@link #HANDLE_DESCRIPTOR}.
+ * @param value an internal name (see {@link Type#getInternalName()}), type descriptor or a type
+ * signature. May be {@literal null}.
+ */
+ protected void appendDescriptor(final int type, final String value) {
+ if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) {
+ if (value != null) {
+ stringBuilder.append("// signature ").append(value).append('\n');
+ }
+ } else {
+ stringBuilder.append(value);
+ }
+ }
+
+ /**
+ * Appends the Java generic type declaration corresponding to the given signature.
+ *
+ * @param name a class, field or method name.
+ * @param signature a class, field or method signature.
+ */
+ private void appendJavaDeclaration(final String name, final String signature) {
+ TraceSignatureVisitor traceSignatureVisitor = new TraceSignatureVisitor(access);
+ new SignatureReader(signature).accept(traceSignatureVisitor);
+ stringBuilder.append("// declaration: ");
+ if (traceSignatureVisitor.getReturnType() != null) {
+ stringBuilder.append(traceSignatureVisitor.getReturnType());
+ stringBuilder.append(' ');
+ }
+ stringBuilder.append(name);
+ stringBuilder.append(traceSignatureVisitor.getDeclaration());
+ if (traceSignatureVisitor.getExceptions() != null) {
+ stringBuilder.append(" throws ").append(traceSignatureVisitor.getExceptions());
+ }
+ stringBuilder.append('\n');
+ }
+
+ /**
+ * Appends the name of the given label to {@link #stringBuilder}. Constructs a new label name if
+ * the given label does not yet have one.
+ *
+ * @param label a label.
+ */
+ protected void appendLabel(final Label label) {
+ if (labelNames == null) {
+ labelNames = new HashMap<>();
+ }
+ String name = labelNames.get(label);
+ if (name == null) {
+ name = "L" + labelNames.size();
+ labelNames.put(label, name);
+ }
+ stringBuilder.append(name);
+ }
+
+ /**
+ * Appends a string representation of the given handle to {@link #stringBuilder}.
+ *
+ * @param handle a handle.
+ */
+ protected void appendHandle(final Handle handle) {
+ int tag = handle.getTag();
+ stringBuilder.append("// handle kind 0x").append(Integer.toHexString(tag)).append(" : ");
+ boolean isMethodHandle = false;
+ switch (tag) {
+ case Opcodes.H_GETFIELD:
+ stringBuilder.append("GETFIELD");
+ break;
+ case Opcodes.H_GETSTATIC:
+ stringBuilder.append("GETSTATIC");
+ break;
+ case Opcodes.H_PUTFIELD:
+ stringBuilder.append("PUTFIELD");
+ break;
+ case Opcodes.H_PUTSTATIC:
+ stringBuilder.append("PUTSTATIC");
+ break;
+ case Opcodes.H_INVOKEINTERFACE:
+ stringBuilder.append("INVOKEINTERFACE");
+ isMethodHandle = true;
+ break;
+ case Opcodes.H_INVOKESPECIAL:
+ stringBuilder.append("INVOKESPECIAL");
+ isMethodHandle = true;
+ break;
+ case Opcodes.H_INVOKESTATIC:
+ stringBuilder.append("INVOKESTATIC");
+ isMethodHandle = true;
+ break;
+ case Opcodes.H_INVOKEVIRTUAL:
+ stringBuilder.append("INVOKEVIRTUAL");
+ isMethodHandle = true;
+ break;
+ case Opcodes.H_NEWINVOKESPECIAL:
+ stringBuilder.append("NEWINVOKESPECIAL");
+ isMethodHandle = true;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ stringBuilder.append('\n');
+ stringBuilder.append(tab3);
+ appendDescriptor(INTERNAL_NAME, handle.getOwner());
+ stringBuilder.append('.');
+ stringBuilder.append(handle.getName());
+ if (!isMethodHandle) {
+ stringBuilder.append('(');
+ }
+ appendDescriptor(HANDLE_DESCRIPTOR, handle.getDesc());
+ if (!isMethodHandle) {
+ stringBuilder.append(')');
+ }
+ if (handle.isInterface()) {
+ stringBuilder.append(" itf");
+ }
+ }
+
+ /**
+ * Appends a comma to {@link #stringBuilder} if the given number is strictly positive.
+ *
+ * @param numValues a number of 'values visited so far', for instance the number of annotation
+ * values visited so far in an annotation visitor.
+ */
+ private void maybeAppendComma(final int numValues) {
+ if (numValues > 0) {
+ stringBuilder.append(", ");
+ }
+ }
+
+ /**
+ * Appends a string representation of the given type reference to {@link #stringBuilder}.
+ *
+ * @param typeRef a type reference. See {@link TypeReference}.
+ */
+ private void appendTypeReference(final int typeRef) {
+ TypeReference typeReference = new TypeReference(typeRef);
+ switch (typeReference.getSort()) {
+ case TypeReference.CLASS_TYPE_PARAMETER:
+ stringBuilder.append("CLASS_TYPE_PARAMETER ").append(typeReference.getTypeParameterIndex());
+ break;
+ case TypeReference.METHOD_TYPE_PARAMETER:
+ stringBuilder
+ .append("METHOD_TYPE_PARAMETER ")
+ .append(typeReference.getTypeParameterIndex());
+ break;
+ case TypeReference.CLASS_EXTENDS:
+ stringBuilder.append("CLASS_EXTENDS ").append(typeReference.getSuperTypeIndex());
+ break;
+ case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+ stringBuilder
+ .append("CLASS_TYPE_PARAMETER_BOUND ")
+ .append(typeReference.getTypeParameterIndex())
+ .append(", ")
+ .append(typeReference.getTypeParameterBoundIndex());
+ break;
+ case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+ stringBuilder
+ .append("METHOD_TYPE_PARAMETER_BOUND ")
+ .append(typeReference.getTypeParameterIndex())
+ .append(", ")
+ .append(typeReference.getTypeParameterBoundIndex());
+ break;
+ case TypeReference.FIELD:
+ stringBuilder.append("FIELD");
+ break;
+ case TypeReference.METHOD_RETURN:
+ stringBuilder.append("METHOD_RETURN");
+ break;
+ case TypeReference.METHOD_RECEIVER:
+ stringBuilder.append("METHOD_RECEIVER");
+ break;
+ case TypeReference.METHOD_FORMAL_PARAMETER:
+ stringBuilder
+ .append("METHOD_FORMAL_PARAMETER ")
+ .append(typeReference.getFormalParameterIndex());
+ break;
+ case TypeReference.THROWS:
+ stringBuilder.append("THROWS ").append(typeReference.getExceptionIndex());
+ break;
+ case TypeReference.LOCAL_VARIABLE:
+ stringBuilder.append("LOCAL_VARIABLE");
+ break;
+ case TypeReference.RESOURCE_VARIABLE:
+ stringBuilder.append("RESOURCE_VARIABLE");
+ break;
+ case TypeReference.EXCEPTION_PARAMETER:
+ stringBuilder.append("EXCEPTION_PARAMETER ").append(typeReference.getTryCatchBlockIndex());
+ break;
+ case TypeReference.INSTANCEOF:
+ stringBuilder.append("INSTANCEOF");
+ break;
+ case TypeReference.NEW:
+ stringBuilder.append("NEW");
+ break;
+ case TypeReference.CONSTRUCTOR_REFERENCE:
+ stringBuilder.append("CONSTRUCTOR_REFERENCE");
+ break;
+ case TypeReference.METHOD_REFERENCE:
+ stringBuilder.append("METHOD_REFERENCE");
+ break;
+ case TypeReference.CAST:
+ stringBuilder.append("CAST ").append(typeReference.getTypeArgumentIndex());
+ break;
+ case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ stringBuilder
+ .append("CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT ")
+ .append(typeReference.getTypeArgumentIndex());
+ break;
+ case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+ stringBuilder
+ .append("METHOD_INVOCATION_TYPE_ARGUMENT ")
+ .append(typeReference.getTypeArgumentIndex());
+ break;
+ case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ stringBuilder
+ .append("CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT ")
+ .append(typeReference.getTypeArgumentIndex());
+ break;
+ case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+ stringBuilder
+ .append("METHOD_REFERENCE_TYPE_ARGUMENT ")
+ .append(typeReference.getTypeArgumentIndex());
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Appends the given stack map frame types to {@link #stringBuilder}.
+ *
+ * @param numTypes the number of stack map frame types in 'frameTypes'.
+ * @param frameTypes an array of stack map frame types, in the format described in {@link
+ * org.objectweb.asm.MethodVisitor#visitFrame}.
+ */
+ private void appendFrameTypes(final int numTypes, final Object[] frameTypes) {
+ for (int i = 0; i < numTypes; ++i) {
+ if (i > 0) {
+ stringBuilder.append(' ');
+ }
+ if (frameTypes[i] instanceof String) {
+ String descriptor = (String) frameTypes[i];
+ if (descriptor.charAt(0) == '[') {
+ appendDescriptor(FIELD_DESCRIPTOR, descriptor);
+ } else {
+ appendDescriptor(INTERNAL_NAME, descriptor);
+ }
+ } else if (frameTypes[i] instanceof Integer) {
+ stringBuilder.append(FRAME_TYPES.get(((Integer) frameTypes[i]).intValue()));
+ } else {
+ appendLabel((Label) frameTypes[i]);
+ }
+ }
+ }
+
+ /**
+ * Creates and adds to {@link #text} a new {@link Textifier}, followed by the given string.
+ *
+ * @param endText the text to add to {@link #text} after the textifier. May be {@literal null}.
+ * @return the newly created {@link Textifier}.
+ */
+ private Textifier addNewTextifier(final String endText) {
+ Textifier textifier = createTextifier();
+ text.add(textifier.getText());
+ if (endText != null) {
+ text.add(endText);
+ }
+ return textifier;
+ }
+
+ /**
+ * Creates a new {@link Textifier}.
+ *
+ * @return a new {@link Textifier}.
+ */
+ protected Textifier createTextifier() {
+ return new Textifier(api);
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TextifierSupport.java b/asm-util/src/main/java/org/objectweb/asm/util/TextifierSupport.java
new file mode 100644
index 00000000..d6ea219c
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TextifierSupport.java
@@ -0,0 +1,41 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
+ * France Telecom All rights reserved.
+ *
+ * <p>Redistribution and use in source and binary forms, with or without modification, are permitted
+ * provided that the following conditions are met: 1. Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
+ * in binary form must reproduce the above copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific prior written permission.
+ *
+ * <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.util.Map;
+import org.objectweb.asm.Label;
+
+/**
+ * An {@link org.objectweb.asm.Attribute} that can print a readable representation of itself.
+ *
+ * @author Eugene Kuleshov
+ */
+public interface TextifierSupport {
+
+ /**
+ * Generates a human readable representation of this attribute.
+ *
+ * @param outputBuilder where the human representation of this attribute must be appended.
+ * @param labelNames the human readable names of the labels.
+ */
+ void textify(StringBuilder outputBuilder, Map<Label, String> labelNames);
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java
new file mode 100644
index 00000000..3b156924
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java
@@ -0,0 +1,93 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * An {@link AnnotationVisitor} that prints the annotations it visits with a {@link Printer}.
+ *
+ * @author Eric Bruneton
+ */
+public final class TraceAnnotationVisitor extends AnnotationVisitor {
+
+ /** The printer to convert the visited annotation into text. */
+ private final Printer printer;
+
+ /**
+ * Constructs a new {@link TraceAnnotationVisitor}.
+ *
+ * @param printer the printer to convert the visited annotation into text.
+ */
+ public TraceAnnotationVisitor(final Printer printer) {
+ this(null, printer);
+ }
+
+ /**
+ * Constructs a new {@link TraceAnnotationVisitor}.
+ *
+ * @param annotationVisitor the annotation visitor to which to delegate calls. May be {@literal
+ * null}.
+ * @param printer the printer to convert the visited annotation into text.
+ */
+ public TraceAnnotationVisitor(final AnnotationVisitor annotationVisitor, final Printer printer) {
+ super(/* latest api = */ Opcodes.ASM9, annotationVisitor);
+ this.printer = printer;
+ }
+
+ @Override
+ public void visit(final String name, final Object value) {
+ printer.visit(name, value);
+ super.visit(name, value);
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ printer.visitEnum(name, descriptor, value);
+ super.visitEnum(name, descriptor, value);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ Printer annotationPrinter = printer.visitAnnotation(name, descriptor);
+ return new TraceAnnotationVisitor(super.visitAnnotation(name, descriptor), annotationPrinter);
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ Printer arrayPrinter = printer.visitArray(name);
+ return new TraceAnnotationVisitor(super.visitArray(name), arrayPrinter);
+ }
+
+ @Override
+ public void visitEnd() {
+ printer.visitAnnotationEnd();
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java
new file mode 100644
index 00000000..953e1149
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java
@@ -0,0 +1,244 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.io.PrintWriter;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link ClassVisitor} that prints the classes it visits with a {@link Printer}. This class
+ * visitor can be used in the middle of a class visitor chain to trace the class that is visited at
+ * a given point in this chain. This may be useful for debugging purposes.
+ *
+ * <p>When used with a {@link Textifier}, the trace printed when visiting the {@code Hello} class is
+ * the following:
+ *
+ * <pre>
+ * // class version 49.0 (49) // access flags 0x21 public class Hello {
+ *
+ * // compiled from: Hello.java
+ *
+ * // access flags 0x1
+ * public &lt;init&gt; ()V
+ * ALOAD 0
+ * INVOKESPECIAL java/lang/Object &lt;init&gt; ()V
+ * RETURN
+ * MAXSTACK = 1 MAXLOCALS = 1
+ *
+ * // access flags 0x9
+ * public static main ([Ljava/lang/String;)V
+ * GETSTATIC java/lang/System out Ljava/io/PrintStream;
+ * LDC &quot;hello&quot;
+ * INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
+ * RETURN
+ * MAXSTACK = 2 MAXLOCALS = 1
+ * }
+ * </pre>
+ *
+ * <p>where {@code Hello} is defined by:
+ *
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main(String[] args) {
+ * System.out.println(&quot;hello&quot;);
+ * }
+ * }
+ * </pre>
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public final class TraceClassVisitor extends ClassVisitor {
+
+ /** The print writer to be used to print the class. May be {@literal null}. */
+ private final PrintWriter printWriter;
+
+ /** The printer to convert the visited class into text. */
+ // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
+ public final Printer p;
+
+ /**
+ * Constructs a new {@link TraceClassVisitor}.
+ *
+ * @param printWriter the print writer to be used to print the class. May be {@literal null}.
+ */
+ public TraceClassVisitor(final PrintWriter printWriter) {
+ this(null, printWriter);
+ }
+
+ /**
+ * Constructs a new {@link TraceClassVisitor}.
+ *
+ * @param classVisitor the class visitor to which to delegate calls. May be {@literal null}.
+ * @param printWriter the print writer to be used to print the class. May be {@literal null}.
+ */
+ public TraceClassVisitor(final ClassVisitor classVisitor, final PrintWriter printWriter) {
+ this(classVisitor, new Textifier(), printWriter);
+ }
+
+ /**
+ * Constructs a new {@link TraceClassVisitor}.
+ *
+ * @param classVisitor the class visitor to which to delegate calls. May be {@literal null}.
+ * @param printer the printer to convert the visited class into text.
+ * @param printWriter the print writer to be used to print the class. May be {@literal null}.
+ */
+ public TraceClassVisitor(
+ final ClassVisitor classVisitor, final Printer printer, final PrintWriter printWriter) {
+ super(/* latest api = */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ this.printWriter = printWriter;
+ this.p = printer;
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ p.visit(version, access, name, signature, superName, interfaces);
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public void visitSource(final String file, final String debug) {
+ p.visitSource(file, debug);
+ super.visitSource(file, debug);
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int flags, final String version) {
+ Printer modulePrinter = p.visitModule(name, flags, version);
+ return new TraceModuleVisitor(super.visitModule(name, flags, version), modulePrinter);
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {
+ p.visitNestHost(nestHost);
+ super.visitNestHost(nestHost);
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ p.visitOuterClass(owner, name, descriptor);
+ super.visitOuterClass(owner, name, descriptor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitClassAnnotation(descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitAnnotation(descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitClassTypeAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ p.visitClassAttribute(attribute);
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitNestMember(final String nestMember) {
+ p.visitNestMember(nestMember);
+ super.visitNestMember(nestMember);
+ }
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ p.visitPermittedSubclass(permittedSubclass);
+ super.visitPermittedSubclass(permittedSubclass);
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ p.visitInnerClass(name, outerName, innerName, access);
+ super.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ Printer recordComponentPrinter = p.visitRecordComponent(name, descriptor, signature);
+ return new TraceRecordComponentVisitor(
+ super.visitRecordComponent(name, descriptor, signature), recordComponentPrinter);
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ Printer fieldPrinter = p.visitField(access, name, descriptor, signature, value);
+ return new TraceFieldVisitor(
+ super.visitField(access, name, descriptor, signature, value), fieldPrinter);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ Printer methodPrinter = p.visitMethod(access, name, descriptor, signature, exceptions);
+ return new TraceMethodVisitor(
+ super.visitMethod(access, name, descriptor, signature, exceptions), methodPrinter);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitClassEnd();
+ if (printWriter != null) {
+ p.print(printWriter);
+ printWriter.flush();
+ }
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java
new file mode 100644
index 00000000..eaab60a6
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java
@@ -0,0 +1,93 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link FieldVisitor} that prints the fields it visits with a {@link Printer}.
+ *
+ * @author Eric Bruneton
+ */
+public final class TraceFieldVisitor extends FieldVisitor {
+
+ /** The printer to convert the visited field into text. */
+ // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
+ public final Printer p;
+
+ /**
+ * Constructs a new {@link TraceFieldVisitor}.
+ *
+ * @param printer the printer to convert the visited field into text.
+ */
+ public TraceFieldVisitor(final Printer printer) {
+ this(null, printer);
+ }
+
+ /**
+ * Constructs a new {@link TraceFieldVisitor}.
+ *
+ * @param fieldVisitor the field visitor to which to delegate calls. May be {@literal null}.
+ * @param printer the printer to convert the visited field into text.
+ */
+ public TraceFieldVisitor(final FieldVisitor fieldVisitor, final Printer printer) {
+ super(/* latest api = */ Opcodes.ASM9, fieldVisitor);
+ this.p = printer;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitFieldAnnotation(descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitAnnotation(descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitFieldTypeAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ p.visitFieldAttribute(attribute);
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitFieldEnd();
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java
new file mode 100644
index 00000000..073c55db
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java
@@ -0,0 +1,312 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link MethodVisitor} that prints the methods it visits with a {@link Printer}.
+ *
+ * @author Eric Bruneton
+ */
+public final class TraceMethodVisitor extends MethodVisitor {
+
+ /** The printer to convert the visited method into text. */
+ // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
+ public final Printer p;
+
+ /**
+ * Constructs a new {@link TraceMethodVisitor}.
+ *
+ * @param printer the printer to convert the visited method into text.
+ */
+ public TraceMethodVisitor(final Printer printer) {
+ this(null, printer);
+ }
+
+ /**
+ * Constructs a new {@link TraceMethodVisitor}.
+ *
+ * @param methodVisitor the method visitor to which to delegate calls. May be {@literal null}.
+ * @param printer the printer to convert the visited method into text.
+ */
+ public TraceMethodVisitor(final MethodVisitor methodVisitor, final Printer printer) {
+ super(/* latest api = */ Opcodes.ASM9, methodVisitor);
+ this.p = printer;
+ }
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ p.visitParameter(name, access);
+ super.visitParameter(name, access);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitMethodAnnotation(descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitAnnotation(descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitMethodTypeAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ p.visitMethodAttribute(attribute);
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ Printer annotationPrinter = p.visitAnnotationDefault();
+ return new TraceAnnotationVisitor(super.visitAnnotationDefault(), annotationPrinter);
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ p.visitAnnotableParameterCount(parameterCount, visible);
+ super.visitAnnotableParameterCount(parameterCount, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitParameterAnnotation(parameter, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitParameterAnnotation(parameter, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitCode() {
+ p.visitCode();
+ super.visitCode();
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ p.visitFrame(type, numLocal, local, numStack, stack);
+ super.visitFrame(type, numLocal, local, numStack, stack);
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ p.visitInsn(opcode);
+ super.visitInsn(opcode);
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ p.visitIntInsn(opcode, operand);
+ super.visitIntInsn(opcode, operand);
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ p.visitVarInsn(opcode, varIndex);
+ super.visitVarInsn(opcode, varIndex);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ p.visitTypeInsn(opcode, type);
+ super.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ p.visitFieldInsn(opcode, owner, name, descriptor);
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ // Call the method that p is supposed to implement, depending on its api version.
+ if (p.api < Opcodes.ASM5) {
+ if (isInterface != (opcode == Opcodes.INVOKEINTERFACE)) {
+ throw new IllegalArgumentException("INVOKESPECIAL/STATIC on interfaces require ASM5");
+ }
+ // If p is an ASMifier (resp. Textifier), or a subclass that does not override the old
+ // visitMethodInsn method, the default implementation in Printer will redirect this to the
+ // new method in ASMifier (resp. Textifier). In all other cases, p overrides the old method
+ // and this call executes it.
+ p.visitMethodInsn(opcode, owner, name, descriptor);
+ } else {
+ p.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ if (mv != null) {
+ mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ p.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ p.visitJumpInsn(opcode, label);
+ super.visitJumpInsn(opcode, label);
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ p.visitLabel(label);
+ super.visitLabel(label);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ p.visitLdcInsn(value);
+ super.visitLdcInsn(value);
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ p.visitIincInsn(varIndex, increment);
+ super.visitIincInsn(varIndex, increment);
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ p.visitTableSwitchInsn(min, max, dflt, labels);
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ p.visitLookupSwitchInsn(dflt, keys, labels);
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ p.visitMultiANewArrayInsn(descriptor, numDimensions);
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitInsnAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ p.visitTryCatchBlock(start, end, handler, type);
+ super.visitTryCatchBlock(start, end, handler, type);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter = p.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ p.visitLocalVariable(name, descriptor, signature, start, end, index);
+ super.visitLocalVariable(name, descriptor, signature, start, end, index);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ Printer annotationPrinter =
+ p.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible),
+ annotationPrinter);
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ p.visitLineNumber(line, start);
+ super.visitLineNumber(line, start);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ p.visitMaxs(maxStack, maxLocals);
+ super.visitMaxs(maxStack, maxLocals);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitMethodEnd();
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java
new file mode 100644
index 00000000..2d04a6a5
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java
@@ -0,0 +1,111 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that prints the fields it visits with a {@link Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceModuleVisitor extends ModuleVisitor {
+
+ /** The printer to convert the visited module into text. */
+ // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
+ public final Printer p;
+
+ /**
+ * Constructs a new {@link TraceModuleVisitor}.
+ *
+ * @param printer the printer to convert the visited module into text.
+ */
+ public TraceModuleVisitor(final Printer printer) {
+ this(null, printer);
+ }
+
+ /**
+ * Constructs a new {@link TraceModuleVisitor}.
+ *
+ * @param moduleVisitor the module visitor to which to delegate calls. May be {@literal null}.
+ * @param printer the printer to convert the visited module into text.
+ */
+ public TraceModuleVisitor(final ModuleVisitor moduleVisitor, final Printer printer) {
+ super(/* latest api = */ Opcodes.ASM9, moduleVisitor);
+ this.p = printer;
+ }
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ p.visitMainClass(mainClass);
+ super.visitMainClass(mainClass);
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ p.visitPackage(packaze);
+ super.visitPackage(packaze);
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ p.visitRequire(module, access, version);
+ super.visitRequire(module, access, version);
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ p.visitExport(packaze, access, modules);
+ super.visitExport(packaze, access, modules);
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ p.visitOpen(packaze, access, modules);
+ super.visitOpen(packaze, access, modules);
+ }
+
+ @Override
+ public void visitUse(final String use) {
+ p.visitUse(use);
+ super.visitUse(use);
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ p.visitProvide(service, providers);
+ super.visitProvide(service, providers);
+ }
+
+ @Override
+ public void visitEnd() {
+ p.visitModuleEnd();
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceRecordComponentVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceRecordComponentVisitor.java
new file mode 100644
index 00000000..882d0877
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceRecordComponentVisitor.java
@@ -0,0 +1,96 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link RecordComponentVisitor} that prints the record components it visits with a {@link
+ * Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceRecordComponentVisitor extends RecordComponentVisitor {
+
+ /** The printer to convert the visited record component into text. */
+ public final Printer printer;
+
+ /**
+ * Constructs a new {@link TraceRecordComponentVisitor}.
+ *
+ * @param printer the printer to convert the visited record component into text.
+ */
+ public TraceRecordComponentVisitor(final Printer printer) {
+ this(null, printer);
+ }
+
+ /**
+ * Constructs a new {@link TraceRecordComponentVisitor}.
+ *
+ * @param recordComponentVisitor the record component visitor to which to delegate calls. May be
+ * {@literal null}.
+ * @param printer the printer to convert the visited record component into text.
+ */
+ public TraceRecordComponentVisitor(
+ final RecordComponentVisitor recordComponentVisitor, final Printer printer) {
+ super(/* latest api ='*/ Opcodes.ASM9, recordComponentVisitor);
+ this.printer = printer;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ Printer annotationPrinter = printer.visitRecordComponentAnnotation(descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitAnnotation(descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ Printer annotationPrinter =
+ printer.visitRecordComponentTypeAnnotation(typeRef, typePath, descriptor, visible);
+ return new TraceAnnotationVisitor(
+ super.visitTypeAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ printer.visitRecordComponentAttribute(attribute);
+ super.visitAttribute(attribute);
+ }
+
+ @Override
+ public void visitEnd() {
+ printer.visitRecordComponentEnd();
+ super.visitEnd();
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java
new file mode 100644
index 00000000..8909d96f
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java
@@ -0,0 +1,344 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+/**
+ * A {@link SignatureVisitor} that builds the Java generic type declaration corresponding to the
+ * signature it visits.
+ *
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+public final class TraceSignatureVisitor extends SignatureVisitor {
+
+ private static final String COMMA_SEPARATOR = ", ";
+ private static final String EXTENDS_SEPARATOR = " extends ";
+ private static final String IMPLEMENTS_SEPARATOR = " implements ";
+
+ private static final Map<Character, String> BASE_TYPES;
+
+ static {
+ HashMap<Character, String> baseTypes = new HashMap<>();
+ baseTypes.put('Z', "boolean");
+ baseTypes.put('B', "byte");
+ baseTypes.put('C', "char");
+ baseTypes.put('S', "short");
+ baseTypes.put('I', "int");
+ baseTypes.put('J', "long");
+ baseTypes.put('F', "float");
+ baseTypes.put('D', "double");
+ baseTypes.put('V', "void");
+ BASE_TYPES = Collections.unmodifiableMap(baseTypes);
+ }
+
+ /** Whether the visited signature is a class signature of a Java interface. */
+ private final boolean isInterface;
+
+ /** The Java generic type declaration corresponding to the visited signature. */
+ private final StringBuilder declaration;
+
+ /** The Java generic method return type declaration corresponding to the visited signature. */
+ private StringBuilder returnType;
+
+ /** The Java generic exception types declaration corresponding to the visited signature. */
+ private StringBuilder exceptions;
+
+ /** Whether {@link #visitFormalTypeParameter} has been called. */
+ private boolean formalTypeParameterVisited;
+
+ /** Whether {@link #visitInterfaceBound} has been called. */
+ private boolean interfaceBoundVisited;
+
+ /** Whether {@link #visitParameterType} has been called. */
+ private boolean parameterTypeVisited;
+
+ /** Whether {@link #visitInterface} has been called. */
+ private boolean interfaceVisited;
+
+ /**
+ * The stack used to keep track of class types that have arguments. Each element of this stack is
+ * a boolean encoded in one bit. The top of the stack is the least significant bit. Pushing false
+ * = *2, pushing true = *2+1, popping = /2.
+ */
+ private int argumentStack;
+
+ /**
+ * The stack used to keep track of array class types. Each element of this stack is a boolean
+ * encoded in one bit. The top of the stack is the lowest order bit. Pushing false = *2, pushing
+ * true = *2+1, popping = /2.
+ */
+ private int arrayStack;
+
+ /** The separator to append before the next visited class or inner class type. */
+ private String separator = "";
+
+ /**
+ * Constructs a new {@link TraceSignatureVisitor}.
+ *
+ * @param accessFlags for class type signatures, the access flags of the class.
+ */
+ public TraceSignatureVisitor(final int accessFlags) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.isInterface = (accessFlags & Opcodes.ACC_INTERFACE) != 0;
+ this.declaration = new StringBuilder();
+ }
+
+ private TraceSignatureVisitor(final StringBuilder stringBuilder) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.isInterface = false;
+ this.declaration = stringBuilder;
+ }
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ declaration.append(formalTypeParameterVisited ? COMMA_SEPARATOR : "<").append(name);
+ formalTypeParameterVisited = true;
+ interfaceBoundVisited = false;
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ separator = EXTENDS_SEPARATOR;
+ startType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ separator = interfaceBoundVisited ? COMMA_SEPARATOR : EXTENDS_SEPARATOR;
+ interfaceBoundVisited = true;
+ startType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ endFormals();
+ separator = EXTENDS_SEPARATOR;
+ startType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ if (interfaceVisited) {
+ separator = COMMA_SEPARATOR;
+ } else {
+ separator = isInterface ? EXTENDS_SEPARATOR : IMPLEMENTS_SEPARATOR;
+ interfaceVisited = true;
+ }
+ startType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ endFormals();
+ if (parameterTypeVisited) {
+ declaration.append(COMMA_SEPARATOR);
+ } else {
+ declaration.append('(');
+ parameterTypeVisited = true;
+ }
+ startType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ endFormals();
+ if (parameterTypeVisited) {
+ parameterTypeVisited = false;
+ } else {
+ declaration.append('(');
+ }
+ declaration.append(')');
+ returnType = new StringBuilder();
+ return new TraceSignatureVisitor(returnType);
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ if (exceptions == null) {
+ exceptions = new StringBuilder();
+ } else {
+ exceptions.append(COMMA_SEPARATOR);
+ }
+ return new TraceSignatureVisitor(exceptions);
+ }
+
+ @Override
+ public void visitBaseType(final char descriptor) {
+ String baseType = BASE_TYPES.get(descriptor);
+ if (baseType == null) {
+ throw new IllegalArgumentException();
+ }
+ declaration.append(baseType);
+ endType();
+ }
+
+ @Override
+ public void visitTypeVariable(final String name) {
+ declaration.append(separator).append(name);
+ separator = "";
+ endType();
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ startType();
+ arrayStack |= 1;
+ return this;
+ }
+
+ @Override
+ public void visitClassType(final String name) {
+ if ("java/lang/Object".equals(name)) {
+ // 'Map<java.lang.Object,java.util.List>' or 'abstract public V get(Object key);' should have
+ // Object 'but java.lang.String extends java.lang.Object' is unnecessary.
+ boolean needObjectClass = argumentStack % 2 != 0 || parameterTypeVisited;
+ if (needObjectClass) {
+ declaration.append(separator).append(name.replace('/', '.'));
+ }
+ } else {
+ declaration.append(separator).append(name.replace('/', '.'));
+ }
+ separator = "";
+ argumentStack *= 2;
+ }
+
+ @Override
+ public void visitInnerClassType(final String name) {
+ if (argumentStack % 2 != 0) {
+ declaration.append('>');
+ }
+ argumentStack /= 2;
+ declaration.append('.');
+ declaration.append(separator).append(name.replace('/', '.'));
+ separator = "";
+ argumentStack *= 2;
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ declaration.append('<');
+ } else {
+ declaration.append(COMMA_SEPARATOR);
+ }
+ declaration.append('?');
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(final char tag) {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ declaration.append('<');
+ } else {
+ declaration.append(COMMA_SEPARATOR);
+ }
+
+ if (tag == EXTENDS) {
+ declaration.append("? extends ");
+ } else if (tag == SUPER) {
+ declaration.append("? super ");
+ }
+
+ startType();
+ return this;
+ }
+
+ @Override
+ public void visitEnd() {
+ if (argumentStack % 2 != 0) {
+ declaration.append('>');
+ }
+ argumentStack /= 2;
+ endType();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the Java generic type declaration corresponding to the visited signature.
+ *
+ * @return the Java generic type declaration corresponding to the visited signature.
+ */
+ public String getDeclaration() {
+ return declaration.toString();
+ }
+
+ /**
+ * Returns the Java generic method return type declaration corresponding to the visited signature.
+ *
+ * @return the Java generic method return type declaration corresponding to the visited signature.
+ */
+ public String getReturnType() {
+ return returnType == null ? null : returnType.toString();
+ }
+
+ /**
+ * Returns the Java generic exception types declaration corresponding to the visited signature.
+ *
+ * @return the Java generic exception types declaration corresponding to the visited signature.
+ */
+ public String getExceptions() {
+ return exceptions == null ? null : exceptions.toString();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ private void endFormals() {
+ if (formalTypeParameterVisited) {
+ declaration.append('>');
+ formalTypeParameterVisited = false;
+ }
+ }
+
+ private void startType() {
+ arrayStack *= 2;
+ }
+
+ private void endType() {
+ if (arrayStack % 2 == 0) {
+ arrayStack /= 2;
+ } else {
+ while (arrayStack % 2 != 0) {
+ arrayStack /= 2;
+ declaration.append("[]");
+ }
+ }
+ }
+}
diff --git a/asm-util/src/main/java/org/objectweb/asm/util/package.html b/asm-util/src/main/java/org/objectweb/asm/util/package.html
new file mode 100644
index 00000000..d2fed34c
--- /dev/null
+++ b/asm-util/src/main/java/org/objectweb/asm/util/package.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm.util</title>
+</head>
+<body>
+Provides ASM visitors that can be useful for programming and
+debugging purposes. These class visitors are normally not used by applications
+at runtime. This is why they are bundled in an optional <code>asm-util.jar</code>
+library that is separated from (but requires) the <code>asm.jar</code> library,
+which contains the core ASM framework.
+
+@since ASM 1.3.2
+</body>
+</html>
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java b/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java
new file mode 100644
index 00000000..e616042f
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/ASMifierTest.java
@@ -0,0 +1,225 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import org.codehaus.commons.compiler.CompileException;
+import org.codehaus.janino.ClassLoaderIClassLoader;
+import org.codehaus.janino.IClassLoader;
+import org.codehaus.janino.Parser;
+import org.codehaus.janino.Scanner;
+import org.codehaus.janino.UnitCompiler;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link ASMifier}.
+ *
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+// DontCheck(AbbreviationAsWordInName)
+class ASMifierTest extends AsmTest {
+
+ private static final String EXPECTED_USAGE =
+ "Prints the ASM code to generate the given class.\n"
+ + "Usage: ASMifier [-nodebug] <fully qualified class name or class file name>";
+
+ private static final IClassLoader ICLASS_LOADER =
+ new ClassLoaderIClassLoader(new URLClassLoader(new URL[0]));
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new ASMifier());
+ assertThrows(IllegalStateException.class, () -> new ASMifier() {});
+ }
+
+ /**
+ * Tests that the code produced with an ASMifier compiles and generates the original class.
+ *
+ * @throws Exception if something goes wrong.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAsmify_precompiledClass(final PrecompiledClass classParameter, final Api apiParameter)
+ throws Exception {
+ byte[] classFile = classParameter.getBytes();
+ assumeTrue(classFile.length < Short.MAX_VALUE);
+ StringWriter output = new StringWriter();
+ TraceClassVisitor asmifier =
+ new TraceClassVisitor(
+ null,
+ new ASMifier(apiParameter.value(), "classWriter", 0) {},
+ new PrintWriter(output, true));
+
+ new ClassReader(classFile)
+ .accept(asmifier, new Attribute[] {new Comment(), new CodeComment()}, 0);
+
+ // Janino can't compile JDK9 modules.
+ assumeTrue(classParameter != PrecompiledClass.JDK9_MODULE);
+ byte[] asmifiedClassFile = compile(classParameter.getName(), output.toString());
+ Class<?> asmifiedClass = new ClassFile(asmifiedClassFile).newInstance().getClass();
+ byte[] dumpClassFile = (byte[]) asmifiedClass.getMethod("dump").invoke(null);
+ assertEquals(new ClassFile(classFile), new ClassFile(dumpClassFile));
+ }
+
+ private static byte[] compile(final String name, final String source) throws IOException {
+ Parser parser = new Parser(new Scanner(name, new StringReader(source)));
+ try {
+ UnitCompiler unitCompiler =
+ new UnitCompiler(parser.parseAbstractCompilationUnit(), ICLASS_LOADER);
+ return unitCompiler.compileUnit(true, true, true)[0].toByteArray();
+ } catch (CompileException e) {
+ throw new AssertionError(source, e);
+ }
+ }
+
+ @Test
+ void testMain_missingClassName() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = new String[0];
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_missingClassName_withNodebug() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug"};
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_tooManyArguments() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug", getClass().getName(), "extraArgument"};
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_classFileNotFound() {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"DoNotExist.class"};
+
+ Executable main =
+ () -> ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", output.toString());
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classNotFound() {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"do\\not\\exist"};
+
+ Executable main =
+ () -> ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", output.toString());
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_className() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {getClass().getName()};
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("public class ASMifierTestDump implements Opcodes"));
+ assertTrue(output.toString().contains("\nmethodVisitor.visitLineNumber("));
+ assertTrue(output.toString().contains("\nmethodVisitor.visitLocalVariable("));
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_className_withNodebug() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug", getClass().getName()};
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("public class ASMifierTestDump implements Opcodes"));
+ assertFalse(output.toString().contains("\nmethodVisitor.visitLineNumber("));
+ assertFalse(output.toString().contains("\nmethodVisitor.visitLocalVariable("));
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classFile() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {
+ ClassLoader.getSystemResource(getClass().getName().replace('.', '/') + ".class").getPath()
+ };
+
+ ASMifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("public class ASMifierTestDump implements Opcodes"));
+ assertEquals("", logger.toString());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java
new file mode 100644
index 00000000..8276a0f8
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckAnnotationAdapterTest.java
@@ -0,0 +1,96 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link CheckAnnotationAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckAnnotationAdapterTest extends AsmTest {
+
+ @Test
+ void testVisit_illegalAnnotationName() {
+ CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
+
+ Executable visit = () -> checkAnnotationAdapter.visit(null, Integer.valueOf(0));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("Annotation value name must not be null", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalAnnotationValue1() {
+ CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
+
+ Executable visit = () -> checkAnnotationAdapter.visit("name", new Object());
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("Invalid annotation value", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalAnnotationValue2() {
+ CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
+
+ Executable visit = () -> checkAnnotationAdapter.visit("name", Type.getMethodType("()V"));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("Invalid annotation value", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_afterEnd() {
+ CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
+ checkAnnotationAdapter.visitEnd();
+
+ Executable visit = () -> checkAnnotationAdapter.visit("name", Integer.valueOf(0));
+
+ Exception exception = assertThrows(IllegalStateException.class, visit);
+ assertEquals(
+ "Cannot call a visit method after visitEnd has been called", exception.getMessage());
+ }
+
+ @Test
+ void testVisitEnum_illegalAnnotationEnumValue() {
+ CheckAnnotationAdapter checkAnnotationAdapter = new CheckAnnotationAdapter(null);
+
+ Executable visitEnum = () -> checkAnnotationAdapter.visitEnum("name", "Lpkg/Enum;", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnum);
+ assertEquals("Invalid enum value", exception.getMessage());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java
new file mode 100644
index 00000000..280ec628
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java
@@ -0,0 +1,664 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+
+/**
+ * Unit tests for {@link CheckClassAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckClassAdapterTest extends AsmTest implements Opcodes {
+
+ private static final String EXPECTED_USAGE =
+ "Verifies the given class.\n"
+ + "Usage: CheckClassAdapter <fully qualified class name or class file name>";
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new CheckClassAdapter(null));
+ assertThrows(IllegalStateException.class, () -> new CheckClassAdapter(null) {});
+ }
+
+ @Test
+ void testVisit_illegalClassAccessFlag() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () -> checkClassAdapter.visit(V1_1, 1 << 20, "C", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("Invalid access flags: 1048576", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalClassName() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit = () -> checkClassAdapter.visit(V1_1, 0, null, null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("Illegal class name (null)", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_nonJavaIdentifierClassNamePre15() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () -> checkClassAdapter.visit(V1_4, 0, "class name", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals(
+ "Invalid class name (must be an internal class name): class name", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_nonJavaIdentifierClassNamePost15() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () -> checkClassAdapter.visit(V1_5, 0, "class name", null, "java/lang/Object", null);
+
+ assertDoesNotThrow(visit);
+ }
+
+ @Test
+ void testVisit_illegalSuperClass() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () ->
+ checkClassAdapter.visit(
+ V1_1, ACC_PUBLIC, "java/lang/Object", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("The super class name of the Object class must be 'null'", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_moduleInfoSuperClass() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () ->
+ checkClassAdapter.visit(
+ V1_1, ACC_PUBLIC, "module-info", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals(
+ "The super class name of a module-info class must be 'null'", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalInterfaceSuperClass() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit = () -> checkClassAdapter.visit(V1_1, ACC_INTERFACE, "I", null, "C", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals(
+ "The super class name of interfaces must be 'java/lang/Object'", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalSignature() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () -> checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", "LC;I", "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("LC;I: error at index 3", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalAccessFlagSet() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visit =
+ () ->
+ checkClassAdapter.visit(
+ V1_1, ACC_FINAL + ACC_ABSTRACT, "C", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visit);
+ assertEquals("final and abstract are mutually exclusive: 1040", exception.getMessage());
+ }
+
+ @Test
+ void testVisit_illegalMultipleCalls() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visit =
+ () -> checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visit);
+ assertEquals("visit must be called only once", exception.getMessage());
+ }
+
+ @Test
+ void testVisitModule_illegalModuleName() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitModule = () -> checkClassAdapter.visitModule("pkg.invalid=name", 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitModule);
+ assertEquals(
+ "Invalid module name (must be a fully qualified name): pkg.invalid=name",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitModule_illegalMultipleCalls() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ checkClassAdapter.visitModule("module1", Opcodes.ACC_OPEN, null);
+
+ Executable visitModule = () -> checkClassAdapter.visitModule("module2", 0, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitModule);
+ assertEquals("visitModule can be called only once.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitSource_beforeStart() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+
+ Executable visitSource = () -> checkClassAdapter.visitSource(null, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitSource);
+ assertEquals("Cannot visit member before visit has been called.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitSource_afterEnd() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ checkClassAdapter.visitEnd();
+
+ Executable visitSource = () -> checkClassAdapter.visitSource(null, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitSource);
+ assertEquals("Cannot visit member after visitEnd has been called.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitSource_illegalMultipleCalls() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ checkClassAdapter.visitSource(null, null);
+
+ Executable visitSource = () -> checkClassAdapter.visitSource(null, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitSource);
+ assertEquals("visitSource can be called only once.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitOuterClass_illegalOuterClassName() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitOuterClass = () -> checkClassAdapter.visitOuterClass(null, null, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitOuterClass);
+ assertEquals("Illegal outer class owner", exception.getMessage());
+ }
+
+ @Test
+ void testVisitOuterClass_illegalMultipleCalls() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ checkClassAdapter.visitOuterClass("name", null, null);
+
+ Executable visitOuterClass = () -> checkClassAdapter.visitOuterClass(null, null, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitOuterClass);
+ assertEquals("visitOuterClass can be called only once.", exception.getMessage());
+ }
+
+ @Test
+ void testInnerClass_illegalInnerClassName() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ checkClassAdapter.visitInnerClass("name", "outerName", "0validInnerName", 0);
+
+ Executable visitInnerClass =
+ () -> checkClassAdapter.visitInnerClass("name", "outerName", "0illegalInnerName;", 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitInnerClass);
+ assertEquals(
+ "Invalid inner class name (must be a valid Java identifier): 0illegalInnerName;",
+ exception.getMessage());
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "L;,identifier expected at index 1",
+ "LC+,';' expected at index 3",
+ "LC;I,error at index 3"
+ })
+ void testVisitRecordComponent_illegalRecordComponentSignatures(
+ final String invalidSignature, final String expectedMessage) {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V14, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitRecordComponent =
+ () -> checkClassAdapter.visitRecordComponent("i", "I", invalidSignature);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitRecordComponent);
+ assertEquals(invalidSignature + ": " + expectedMessage, exception.getMessage());
+ }
+
+ @Test
+ void testVisitField_illegalAccessFlagSet() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitField =
+ () -> checkClassAdapter.visitField(ACC_PUBLIC + ACC_PRIVATE, "i", "I", null, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitField);
+ assertEquals("public, protected and private are mutually exclusive: 3", exception.getMessage());
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "L;,identifier expected at index 1",
+ "LC+,';' expected at index 3",
+ "LC;I,error at index 3"
+ })
+ void testVisitField_illegalFieldSignatures(
+ final String invalidSignature, final String expectedMessage) {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitField =
+ () -> checkClassAdapter.visitField(ACC_PUBLIC, "i", "I", invalidSignature, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitField);
+ assertEquals(invalidSignature + ": " + expectedMessage, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethod_illegalAccessFlagSet() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitMethod =
+ () -> checkClassAdapter.visitMethod(ACC_ABSTRACT | ACC_STRICT, "m", "()V", null, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethod);
+ assertEquals("strictfp and abstract are mutually exclusive: 3072", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethod_legalAccessFlagSet_V17() {
+ // Java 17 allows to mix ACC_ABSTRACT and ACC_STRICT because ACC_STRICT is ignored
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V17, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitMethod =
+ () -> checkClassAdapter.visitMethod(ACC_ABSTRACT | ACC_STRICT, "m", "()V", null, null);
+
+ assertDoesNotThrow(visitMethod);
+ }
+
+ @Test
+ void testVisitMethod_illegalSignature() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitMethod =
+ () ->
+ checkClassAdapter.visitMethod(
+ ACC_PUBLIC, "m", "()V", "<T::LI.J<*+LA;>;>()V^LA;X", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethod);
+ assertEquals("<T::LI.J<*+LA;>;>()V^LA;X: error at index 24", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethod_checkDataFlowByDefault() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ checkClassAdapter.visitMethod(ACC_PUBLIC, "m", "(I)I", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ASTORE, 0);
+ methodVisitor.visitInsn(IRETURN);
+ methodVisitor.visitMaxs(0, 0);
+
+ Executable visitEnd = () -> methodVisitor.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith(
+ "Error at instruction 1: Expected an object reference or a return address, but"
+ + " found I m(I)I"));
+ }
+
+ @Test
+ void testVisitMethod_checkMaxStackAndLocalsIfClassWriterWithoutComputeMaxs() {
+ ClassWriter classWriter = new ClassWriter(0);
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(classWriter);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ checkClassAdapter.visitMethod(ACC_PUBLIC, "m", "(I)I", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitInsn(IRETURN);
+ methodVisitor.visitMaxs(0, 2);
+
+ Executable visitEnd = () -> methodVisitor.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith("Error at instruction 0: Insufficient maximum stack size. m(I)I"));
+ }
+
+ @Test
+ void testVisitMethod_noDataFlowCheckIfDisabled() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null, /* checkDataFlow = */ false);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor = checkClassAdapter.visitMethod(ACC_PUBLIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ASTORE, 0);
+ methodVisitor.visitInsn(IRETURN);
+ methodVisitor.visitMaxs(0, 0);
+
+ Executable visitEnd = () -> methodVisitor.visitEnd();
+
+ assertDoesNotThrow(visitEnd);
+ }
+
+ @Test
+ void testVisitTypeAnnotation_illegalAnnotation1() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitTypeAnnotation =
+ () -> checkClassAdapter.visitTypeAnnotation(0xFFFFFFFF, null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeAnnotation);
+ assertEquals("Invalid type reference sort 0xff", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTypeAnnotation_illegalAnnotation2() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitTypeAnnotation =
+ () -> checkClassAdapter.visitTypeAnnotation(0x00FFFFFF, null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeAnnotation);
+ assertEquals("Invalid type reference 0xffffff", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_illegalAttribute() {
+ CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
+ checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+
+ Executable visitAttribute = () -> checkClassAdapter.visitAttribute(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitAttribute);
+ assertEquals("Invalid attribute (must not be null)", exception.getMessage());
+ }
+
+ /**
+ * Tests that classes are unchanged with a ClassReader->CheckClassAdapter->ClassWriter transform.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testVisitMethods_classWriterDelegate_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor classVisitor = new CheckClassAdapter(apiParameter.value(), classWriter, true);
+
+ Executable accept = () -> classReader.accept(classVisitor, attributes(), 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+ }
+
+ /**
+ * Tests that classes are unchanged with a ClassReader->CheckClassAdapter->ClassVisitor transform.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testVisitMethods_nonClassWriterDelegate_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor noOpClassVisitor =
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classWriter) {};
+ ClassVisitor classVisitor = new CheckClassAdapter(apiParameter.value(), noOpClassVisitor, true);
+
+ Executable accept = () -> classReader.accept(classVisitor, attributes(), 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitMethods_noDelegate_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassVisitor classVisitor = new CheckClassAdapter(apiParameter.value(), null, true) {};
+
+ Executable accept = () -> classReader.accept(classVisitor, attributes(), 0);
+
+ assertDoesNotThrow(accept);
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitMethods_noMemberDelegate_precompiledClass(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassVisitor classVisitor =
+ new CheckClassAdapter(
+ apiParameter.value(),
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL, null) {},
+ true) {};
+
+ Executable accept = () -> classReader.accept(classVisitor, attributes(), 0);
+
+ assertDoesNotThrow(accept);
+ }
+
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVerify_precompiledClass(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ StringWriter logger = new StringWriter();
+
+ CheckClassAdapter.verify(
+ classReader, /* printResults = */ false, new PrintWriter(logger, true));
+
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_missingClassName() throws IOException {
+ StringWriter logger = new StringWriter();
+ String[] args = new String[0];
+
+ CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_tooManyArguments() throws IOException {
+ StringWriter logger = new StringWriter();
+ String[] args = {getClass().getName(), "extraArgument"};
+
+ CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_classFileNotFound() {
+ StringWriter logger = new StringWriter();
+ String[] args = {"DoNotExist.class"};
+
+ Executable main = () -> CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classNotFound() {
+ StringWriter logger = new StringWriter();
+ String[] args = {"do\\not\\exist"};
+
+ Executable main = () -> CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_className() throws IOException {
+ StringWriter logger = new StringWriter();
+ String[] args = {getClass().getName()};
+
+ CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classFile() throws IOException {
+ StringWriter logger = new StringWriter();
+ String[] args = {
+ ClassLoader.getSystemResource(getClass().getName().replace('.', '/') + ".class").getPath()
+ };
+
+ CheckClassAdapter.main(args, new PrintWriter(logger, true));
+
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testVerify_validClass() throws Exception {
+ ClassReader classReader = new ClassReader(getClass().getName());
+ StringWriter logger = new StringWriter();
+
+ CheckClassAdapter.verify(classReader, true, new PrintWriter(logger, true));
+
+ String log = logger.toString();
+ assertFalse(log.startsWith(AnalyzerException.class.getName() + ": Error at instruction"));
+ assertTrue(log.contains("00000 CheckClassAdapterTest : : ALOAD 0"));
+ assertTrue(log.contains("00001 CheckClassAdapterTest [Object : [Object : ARETURN"));
+ }
+
+ @Test
+ void testVerify_invalidClass() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 30);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(1, 31);
+ methodVisitor.visitEnd();
+ classWriter.visitEnd();
+ ClassReader classReader = new ClassReader(classWriter.toByteArray());
+ StringWriter logger = new StringWriter();
+
+ CheckClassAdapter.verify(classReader, true, new PrintWriter(logger, true));
+
+ String log = logger.toString();
+ assertTrue(
+ log.startsWith(
+ AnalyzerException.class.getName()
+ + ": Error at instruction 1: Expected I, but found LC;"));
+ }
+
+ private static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ Object methodWithObjectArrayArgument(final Object[] arg) {
+ return arg;
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckFieldAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckFieldAdapterTest.java
new file mode 100644
index 00000000..ae332d57
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckFieldAdapterTest.java
@@ -0,0 +1,86 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link CheckFieldAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckFieldAdapterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new CheckFieldAdapter(null));
+ assertThrows(IllegalStateException.class, () -> new CheckFieldAdapter(null) {});
+ }
+
+ @Test
+ void testVisitTypeAnnotation_illegalTypeAnnotation() {
+ CheckFieldAdapter checkFieldAdapter = new CheckFieldAdapter(null);
+
+ Executable visitTypeAnnotation =
+ () ->
+ checkFieldAdapter.visitTypeAnnotation(
+ TypeReference.newFormalParameterReference(0).getValue(), null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeAnnotation);
+ assertEquals("Invalid type reference sort 0x16", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_illegalAttribute() {
+ CheckFieldAdapter checkFieldAdapter = new CheckFieldAdapter(null);
+
+ Executable visitAttribute = () -> checkFieldAdapter.visitAttribute(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitAttribute);
+ assertEquals("Invalid attribute (must not be null)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_afterEnd() {
+ CheckFieldAdapter checkFieldAdapter = new CheckFieldAdapter(null);
+ checkFieldAdapter.visitEnd();
+
+ Executable visitAttribute = () -> checkFieldAdapter.visitAttribute(new Comment());
+
+ Exception exception = assertThrows(IllegalStateException.class, visitAttribute);
+ assertEquals(
+ "Cannot call a visit method after visitEnd has been called", exception.getMessage());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckFrameAnalyzerTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckFrameAnalyzerTest.java
new file mode 100644
index 00000000..2edd75f7
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckFrameAnalyzerTest.java
@@ -0,0 +1,369 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+
+import java.util.ArrayList;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.objectweb.asm.tree.analysis.BasicValue;
+import org.objectweb.asm.tree.analysis.BasicVerifier;
+import org.objectweb.asm.tree.analysis.Frame;
+
+/**
+ * Unit tests for {@link CheckFrameAnalyzer}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckFrameAnalyzerTest extends AsmTest {
+
+ private static final String CLASS_NAME = "C";
+
+ // Labels used to generate test cases.
+ private final Label label0 = new Label();
+
+ @Test
+ void testAnalyze_invalidJsr() {
+ MethodNode methodNode = new MethodNodeBuilder().jsr(label0).label(label0).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Error at instruction 0: JSR instructions are unsupported"));
+ }
+
+ @Test
+ void testAnalyze_invalidRet() {
+ MethodNode methodNode = new MethodNodeBuilder().ret(0).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Error at instruction 0: RET instructions are unsupported"));
+ }
+
+ @Test
+ void testAnalyze_missingFrameAtJumpTarget() {
+ MethodNode methodNode =
+ new MethodNodeBuilder().iconst_0().ifne(label0).label(label0).vreturn().build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains("Error at instruction 1: Expected stack map frame at instruction 2"));
+ }
+
+ @Test
+ void testAnalyze_missingFrameAfterGoto() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .nop()
+ .go(label0)
+ .nop()
+ .label(label0)
+ .frame(Opcodes.F_SAME, null, null)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains("Error at instruction 1: Expected stack map frame at instruction 2"));
+ }
+
+ @Test
+ void testAnalyze_illegalFrameType() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .nop()
+ .go(label0)
+ .frame(123456, null, null)
+ .nop()
+ .label(label0)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Error at instruction 2: Illegal frame type 123456"));
+ }
+
+ @Test
+ void testAnalyze_invalidAppendFrame() {
+ MethodNode methodNode =
+ new MethodNodeBuilder(/* maxStack = */ 0, /* maxLocals = */ 1)
+ .nop()
+ .frame(Opcodes.F_APPEND, new Object[] {Opcodes.INTEGER}, null)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains("Error at instruction 1: Cannot append more locals than maxLocals"));
+ }
+
+ @Test
+ void testAnalyze_invalidChopFrame() {
+ MethodNode methodNode =
+ new MethodNodeBuilder(/* maxStack = */ 0, /* maxLocals = */ 1)
+ .nop()
+ .frame(Opcodes.F_CHOP, new Object[] {null, null}, null)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(message.contains("Error at instruction 1: Cannot chop more locals than defined"));
+ }
+
+ @Test
+ void testAnalyze_illegalStackMapFrameValue() {
+ MethodNode methodNode =
+ new MethodNodeBuilder(/* maxStack = */ 0, /* maxLocals = */ 2)
+ .nop()
+ .frame(Opcodes.F_APPEND, new Object[] {new Object()}, null)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains("Error at instruction 1: Illegal stack map frame value java.lang.Object"));
+ }
+
+ @Test
+ void testAnalyze_illegalLabelNodeStackMapFrameValue() {
+ MethodNode methodNode =
+ new MethodNodeBuilder(/* maxStack = */ 0, /* maxLocals = */ 2)
+ .nop()
+ .frame(Opcodes.F_APPEND, new Object[] {new LabelNode(label0)}, null)
+ .label(label0)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains("Error at instruction 1: LabelNode does not designate a NEW instruction"));
+ }
+
+ @Test
+ void testAnalyze_frameAtJumpTargetHasIncompatibleStackHeight() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .iconst_0()
+ .ifne(label0)
+ .iconst_0()
+ .label(label0)
+ .frame(Opcodes.F_SAME1, null, new Object[] {Opcodes.INTEGER})
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains(
+ "Error at instruction 1: Stack map frame incompatible with frame at instruction 3 "
+ + "(incompatible stack heights)"));
+ }
+
+ @Test
+ void testAnalyze_frameAtJumpTargetHasIncompatibleLocalValues() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .iconst_0()
+ .ifne(label0)
+ .iconst_0()
+ .label(label0)
+ .frame(Opcodes.F_NEW, new Object[] {Opcodes.INTEGER}, null)
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains(
+ "Error at instruction 1: Stack map frame incompatible with frame at instruction 3 "
+ + "(incompatible types at local 0: R and I)"));
+ }
+
+ @Test
+ void testAnalyze_frameAtJumpTargetHasIncompatibleStackValues() {
+ MethodNode methodNode =
+ new MethodNodeBuilder()
+ .iconst_0()
+ .iconst_0()
+ .ifne(label0)
+ .iconst_0()
+ .iconst_0()
+ .label(label0)
+ .frame(Opcodes.F_NEW, new Object[] {"C"}, new Object[] {"C"})
+ .vreturn()
+ .build();
+
+ Executable analyze = () -> newAnalyzer().analyze(CLASS_NAME, methodNode);
+
+ String message = assertThrows(AnalyzerException.class, analyze).getMessage();
+ assertTrue(
+ message.contains(
+ "Error at instruction 2: Stack map frame incompatible with frame at instruction 5 "
+ + "(incompatible types at stack item 0: I and R)"));
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed from their existing stack map
+ * frames with a BasicVerifier.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyze_basicVerifier(final PrecompiledClass classParameter, final Api apiParameter)
+ throws AnalyzerException {
+ assumeFalse(hasJsrOrRetInstructions(classParameter));
+ ClassNode classNode = computeFrames(classParameter);
+ Analyzer<BasicValue> analyzer = newAnalyzer();
+
+ ArrayList<Frame<? extends BasicValue>[]> methodFrames = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ Frame<? extends BasicValue>[] result = analyzer.analyze(classNode.name, methodNode);
+ methodFrames.add(result);
+ }
+
+ for (int i = 0; i < classNode.methods.size(); ++i) {
+ Frame<? extends BasicValue>[] frames = methodFrames.get(i);
+ for (int j = 0; j < lastJvmInsnIndex(classNode.methods.get(i)); ++j) {
+ assertNotNull(frames[j]);
+ }
+ }
+ }
+
+ /**
+ * Tests that the precompiled classes can be successfully analyzed from their existing stack map
+ * frames with a BasicVerifier, even if the method node's max locals and max stack size are not
+ * set.
+ *
+ * @throws AnalyzerException if the test class can't be analyzed.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testAnalyzeAndComputeMaxs_basicVerifier(
+ final PrecompiledClass classParameter, final Api apiParameter) throws AnalyzerException {
+ assumeFalse(hasJsrOrRetInstructions(classParameter));
+ ClassNode classNode = computeFrames(classParameter);
+ ArrayList<MethodMaxs> methodMaxs = MethodMaxs.getAndClear(classNode);
+ Analyzer<BasicValue> analyzer = newAnalyzer();
+
+ ArrayList<MethodMaxs> analyzedMethodMaxs = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ analyzer.analyzeAndComputeMaxs(classNode.name, methodNode);
+ analyzedMethodMaxs.add(new MethodMaxs(methodNode.maxStack, methodNode.maxLocals));
+ }
+
+ for (int i = 0; i < analyzedMethodMaxs.size(); ++i) {
+ assertTrue(analyzedMethodMaxs.get(i).maxLocals >= methodMaxs.get(i).maxLocals);
+ assertTrue(analyzedMethodMaxs.get(i).maxStack >= methodMaxs.get(i).maxStack);
+ }
+ }
+
+ private static boolean hasJsrOrRetInstructions(final PrecompiledClass classParameter) {
+ return classParameter == PrecompiledClass.JDK3_ALL_INSTRUCTIONS
+ || classParameter == PrecompiledClass.JDK3_LARGE_METHOD;
+ }
+
+ private static ClassNode computeFrames(final PrecompiledClass classParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classReader.accept(classWriter, 0);
+ classFile = classWriter.toByteArray();
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classFile).accept(classNode, 0);
+ return classNode;
+ }
+
+ private static Analyzer<BasicValue> newAnalyzer() {
+ return new CheckFrameAnalyzer<>(new BasicVerifier());
+ }
+
+ private static int lastJvmInsnIndex(final MethodNode method) {
+ for (int i = method.instructions.size() - 1; i >= 0; --i) {
+ if (method.instructions.get(i).getOpcode() >= 0) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static class MethodMaxs {
+
+ final int maxStack;
+ final int maxLocals;
+
+ MethodMaxs(final int maxStack, final int maxLocals) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+
+ static ArrayList<MethodMaxs> getAndClear(final ClassNode classNode) {
+ ArrayList<MethodMaxs> methodMaxs = new ArrayList<>();
+ for (MethodNode methodNode : classNode.methods) {
+ methodMaxs.add(new MethodMaxs(methodNode.maxStack, methodNode.maxLocals));
+ methodNode.maxLocals = 0;
+ methodNode.maxStack = 0;
+ }
+ return methodMaxs;
+ }
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java
new file mode 100644
index 00000000..6652d29b
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckMethodAdapterTest.java
@@ -0,0 +1,1245 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link CheckMethodAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckMethodAdapterTest extends AsmTest implements Opcodes {
+
+ private final CheckMethodAdapter checkMethodAdapter = new CheckMethodAdapter(null);
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new CheckMethodAdapter(null));
+ assertThrows(IllegalStateException.class, () -> new CheckMethodAdapter(null) {});
+ assertThrows(
+ IllegalStateException.class, () -> new CheckMethodAdapter(0, "name", "()V", null, null) {});
+ }
+
+ @Test
+ void testVisitTypeAnnotation_illegalTypeRef() {
+ Executable visitTypeAnnotation =
+ () -> checkMethodAdapter.visitTypeAnnotation(0xFFFFFFFF, null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeAnnotation);
+ assertEquals("Invalid type reference sort 0xff", exception.getMessage());
+ }
+
+ @Test
+ void testVisitParameterAnnotation_invisibleAnnotation_illegalParameterIndex() {
+ checkMethodAdapter.visitAnnotableParameterCount(1, false);
+
+ Executable visitParameterAnnotation =
+ () -> checkMethodAdapter.visitParameterAnnotation(1, "LA;", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitParameterAnnotation);
+ assertEquals("Invalid parameter index", exception.getMessage());
+ }
+
+ @Test
+ void testVisitParameterAnnotation_visibleAnnotation_illegalParameterIndex() {
+ checkMethodAdapter.visitAnnotableParameterCount(2, true);
+
+ Executable visitParameterAnnotation =
+ () -> checkMethodAdapter.visitParameterAnnotation(2, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitParameterAnnotation);
+ assertEquals("Invalid parameter index", exception.getMessage());
+ }
+
+ @Test
+ void testVisitParameterAnnotation_illegalDescriptor() {
+ Executable visitParameterAnnotation =
+ () -> checkMethodAdapter.visitParameterAnnotation(0, "'", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitParameterAnnotation);
+ assertEquals("Invalid descriptor: '", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_afterEnd() {
+ checkMethodAdapter.visitEnd();
+
+ Executable visitAttribute = () -> checkMethodAdapter.visitAttribute(new Comment());
+
+ Exception exception = assertThrows(IllegalStateException.class, visitAttribute);
+ assertEquals("Cannot visit elements after visitEnd has been called.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_nullAttribute() {
+ Executable visitAttribute = () -> checkMethodAdapter.visitAttribute(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitAttribute);
+ assertEquals("Invalid attribute (must not be null)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitCode_abstractMethod() {
+ CheckMethodAdapter checkAbstractMethodAdapter =
+ new CheckMethodAdapter(Opcodes.ACC_ABSTRACT, "m", "()V", null, new HashMap<>());
+
+ Executable visitCode = () -> checkAbstractMethodAdapter.visitCode();
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitCode);
+ assertEquals("Abstract methods cannot have code", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalFrameType() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame = () -> checkMethodAdapter.visitFrame(123, 0, null, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Invalid frame type 123", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalLocalCount() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_SAME, 1, new Object[] {INTEGER}, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Invalid numLocal=1 for frame type 3", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalStackCount() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_SAME, 0, null, 1, new Object[] {INTEGER});
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Invalid numStack=1 for frame type 3", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalLocalArray() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_APPEND, 1, new Object[0], 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Array local[] is shorter than numLocal", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalStackArray() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame = () -> checkMethodAdapter.visitFrame(F_SAME1, 0, null, 1, new Object[0]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Array stack[] is shorter than numStack", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {"LC;"}, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals(
+ "Invalid Invalid stack frame value (must be an internal class name): LC;",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalPrimitiveType() {
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitInsn(NOP);
+ Integer invalidFrameValue =
+ new Integer(0); // NOPMD(IntegerInstantiation): needed to build an invalid value.
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {invalidFrameValue}, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Invalid stack frame value: 0", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalValueClass() {
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitInsn(NOP);
+
+ Executable visitFrame =
+ () -> checkMethodAdapter.visitFrame(F_FULL, 1, new Object[] {Float.valueOf(0.0f)}, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Invalid stack frame value: 0.0", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFrame_illegalMixedFrameTypes() {
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitFrame(F_NEW, 0, null, 0, null);
+ checkMethodAdapter.visitInsn(NOP);
+
+ Executable visitFrame = () -> checkMethodAdapter.visitFrame(F_FULL, 0, null, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertEquals("Expanded and compressed frames must not be mixed.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitInsn_beforeStart() {
+ Executable visitInsn = () -> checkMethodAdapter.visitInsn(NOP);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitInsn);
+ assertEquals(
+ "Cannot visit instructions before visitCode has been called.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitInsn_IllegalInsnVisitAfterEnd() {
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitMaxs(0, 0);
+
+ Executable visitInsn = () -> checkMethodAdapter.visitInsn(NOP);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitInsn);
+ assertEquals(
+ "Cannot visit instructions after visitMaxs has been called.", exception.getMessage());
+ }
+
+ @Test
+ void testVisitIntInsn_illegalOpcode() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitIntInsn = () -> checkMethodAdapter.visitIntInsn(-1, 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitIntInsn);
+ assertEquals("Invalid opcode: -1", exception.getMessage());
+ }
+
+ @Test
+ void testVisitIntInsn_illegalOperand() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitIntInsn = () -> checkMethodAdapter.visitIntInsn(NEWARRAY, 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitIntInsn);
+ assertEquals("Invalid operand (must be an array type code T_...): 0", exception.getMessage());
+ }
+
+ @Test
+ void testVisitIntInsn_illegalByteOperand() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitIntInsn = () -> checkMethodAdapter.visitIntInsn(BIPUSH, Integer.MAX_VALUE);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitIntInsn);
+ assertEquals("Invalid operand (must be a signed byte): 2147483647", exception.getMessage());
+ }
+
+ @Test
+ void testVisitIntInsn_illegalShortOperand() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitIntInsn = () -> checkMethodAdapter.visitIntInsn(SIPUSH, Integer.MAX_VALUE);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitIntInsn);
+ assertEquals("Invalid operand (must be a signed short): 2147483647", exception.getMessage());
+ }
+
+ @Test
+ void testVisitVarInsn_illegalOperand() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitVarInsn = () -> checkMethodAdapter.visitVarInsn(ALOAD, -1);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitVarInsn);
+ assertEquals(
+ "Invalid local variable index (must be an unsigned short): -1", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTypeInsn_illegalOperand() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTypeInsn = () -> checkMethodAdapter.visitTypeInsn(NEW, "[I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeInsn);
+ assertEquals("NEW cannot be used to create arrays: [I", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_nullOwner() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, null, "i", "I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid owner (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidOwnerDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "-", "i", "I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid owner (must be an internal class name): -", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_nullName() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", null, "I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid name (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidFieldName() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "-", "I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid name (must be a valid Java identifier): -", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidFieldName2() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "a-", "I");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid name (must be a valid Java identifier): a-", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_nullDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid type descriptor (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_voidDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", "V");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid descriptor: V", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidPrimitiveDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", "II");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid descriptor: II", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_illegalArrayDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", "[");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid descriptor: [", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidReferenceDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", "L");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid descriptor: L", exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldInsn_invalidReferenceDescriptor2() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitFieldInsn = () -> checkMethodAdapter.visitFieldInsn(GETFIELD, "C", "i", "L-;");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFieldInsn);
+ assertEquals("Invalid descriptor: L-;", exception.getMessage());
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_invalidOpcode() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn = () -> checkMethodAdapter.visitMethodInsn(42, "o", "m", "()V");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid opcode: 42", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidOpcode() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(42, "o", "m", "()V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid opcode: 42", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_nullName() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", null, "()V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid name (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidName() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "-", "()V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals(
+ "Invalid name (must be a '<init>', '<clinit>' or a valid Java identifier): -",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidName2() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "a-", "()V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals(
+ "Invalid name (must be a '<init>', '<clinit>' or a valid Java identifier): a-",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_nullDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "m", null, false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid method descriptor (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "I", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid descriptor: I", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidParameterDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "(V)V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid descriptor: (V)V", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invalidReturnDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()VV", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("Invalid descriptor: ()VV", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_illegalInvokeInterface() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEINTERFACE, "C", "m", "()V", false);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("INVOKEINTERFACE can't be used with classes", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_illegalInvokeInterface2() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()V", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals("INVOKEVIRTUAL can't be used with interfaces", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_illegalInvokeSpecial() {
+ checkMethodAdapter.version = Opcodes.V1_7;
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKESPECIAL, "C", "m", "()V", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMethodInsn);
+ assertEquals(
+ "INVOKESPECIAL can't be used with interfaces prior to Java 8", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_invokeSpecialOnInterface() {
+ checkMethodAdapter.version = Opcodes.V1_8;
+ checkMethodAdapter.visitCode();
+
+ Executable visitMethodInsn =
+ () -> checkMethodAdapter.visitMethodInsn(INVOKESPECIAL, "C", "m", "()V", true);
+
+ assertDoesNotThrow(visitMethodInsn);
+ }
+
+ @Test
+ void testVisitInvokeDynamicInsn_illegalHandleTag() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitInvokeDynamicInsn =
+ () ->
+ checkMethodAdapter.visitInvokeDynamicInsn(
+ "m", "()V", new Handle(Opcodes.GETFIELD, "o", "m", "()V", false));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitInvokeDynamicInsn);
+ assertEquals("invalid handle tag 180", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLabel_alreadyVisitedLabel() {
+ Label label = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(label);
+
+ Executable visitLabel = () -> checkMethodAdapter.visitLabel(label);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitLabel);
+ assertEquals("Already visited label", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v11_illegalOperandType() {
+ checkMethodAdapter.version = Opcodes.V1_1;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn = () -> checkMethodAdapter.visitLdcInsn(new Object());
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertTrue(exception.getMessage().startsWith("Invalid constant: java.lang.Object@"));
+ }
+
+ @Test
+ void testVisitLdcInsn_v11_primitiveDescriptor() {
+ checkMethodAdapter.version = Opcodes.V1_1;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn = () -> checkMethodAdapter.visitLdcInsn(Type.getType("I"));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals("Illegal LDC constant value", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v11_illegalConstantClass() {
+ checkMethodAdapter.version = Opcodes.V1_1;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn = () -> checkMethodAdapter.visitLdcInsn(Type.getObjectType("I"));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals("ldc of a constant class requires at least version 1.5", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v11_methodDescriptor() {
+ checkMethodAdapter.version = Opcodes.V1_1;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn = () -> checkMethodAdapter.visitLdcInsn(Type.getMethodType("()V"));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals("ldc of a method type requires at least version 1.7", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v11_handle() {
+ checkMethodAdapter.version = Opcodes.V1_1;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn =
+ () -> checkMethodAdapter.visitLdcInsn(new Handle(Opcodes.GETFIELD, "o", "m", "()V", false));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals("ldc of a Handle requires at least version 1.7", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v18_invalidHandleTag() {
+ checkMethodAdapter.version = Opcodes.V1_8;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn =
+ () -> checkMethodAdapter.visitLdcInsn(new Handle(-1, "o", "m", "()V", false));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals("invalid handle tag -1", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLdcInsn_v18_handle() {
+ checkMethodAdapter.version = Opcodes.V1_8;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn =
+ () ->
+ checkMethodAdapter.visitLdcInsn(
+ new Handle(Opcodes.H_NEWINVOKESPECIAL, "o", "<init>", "()V", false));
+
+ assertDoesNotThrow(visitLdcInsn);
+ }
+
+ @Test
+ void testVisitLdcInsn_v18_illegalHandleName() {
+ checkMethodAdapter.version = Opcodes.V1_8;
+ checkMethodAdapter.visitCode();
+
+ Executable visitLdcInsn =
+ () ->
+ checkMethodAdapter.visitLdcInsn(
+ new Handle(Opcodes.H_INVOKEVIRTUAL, "o", "<init>", "()V", false));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLdcInsn);
+ assertEquals(
+ "Invalid handle name (must be a valid unqualified name): <init>", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTableSwitchInsn_invalidMinMax() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTableSwitchInsn =
+ () -> checkMethodAdapter.visitTableSwitchInsn(1, 0, new Label(), new Label[0]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTableSwitchInsn);
+ assertEquals("Max = 0 must be greater than or equal to min = 1", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTableSwitchInsn_invalidDefaultLabel() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTableSwitchInsn =
+ () -> checkMethodAdapter.visitTableSwitchInsn(0, 1, null, new Label[0]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTableSwitchInsn);
+ assertEquals("Invalid default label (must not be null)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTableSwitchInsn_nullKeyLabels() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTableSwitchInsn =
+ () -> checkMethodAdapter.visitTableSwitchInsn(0, 1, new Label(), (Label[]) null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTableSwitchInsn);
+ assertEquals("There must be max - min + 1 labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTableSwitchInsn_invalidKeyLabelCount() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTableSwitchInsn =
+ () -> checkMethodAdapter.visitTableSwitchInsn(0, 1, new Label(), new Label[0]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTableSwitchInsn);
+ assertEquals("There must be max - min + 1 labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLookupSwitchInsn_nullKeyArray_oneLabel() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLookupSwitchInsn =
+ () -> checkMethodAdapter.visitLookupSwitchInsn(new Label(), null, new Label[0]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLookupSwitchInsn);
+ assertEquals("There must be the same number of keys and labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLookupSwitchInsn_noKey_nullLabelArray() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLookupSwitchInsn =
+ () -> checkMethodAdapter.visitLookupSwitchInsn(new Label(), new int[0], null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLookupSwitchInsn);
+ assertEquals("There must be the same number of keys and labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLookupSwitchInsn_noKey_oneNullLabel() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLookupSwitchInsn =
+ () -> checkMethodAdapter.visitLookupSwitchInsn(new Label(), new int[0], new Label[1]);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLookupSwitchInsn);
+ assertEquals("There must be the same number of keys and labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMultiANewArrayInsn_invalidDescriptor() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMultiANewArrayInsn = () -> checkMethodAdapter.visitMultiANewArrayInsn("I", 1);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMultiANewArrayInsn);
+ assertEquals(
+ "Invalid descriptor (must be an array type descriptor): I", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMultiANewArrayInsn_notEnoughDimensions() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMultiANewArrayInsn = () -> checkMethodAdapter.visitMultiANewArrayInsn("[[I", 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMultiANewArrayInsn);
+ assertEquals("Invalid dimensions (must be greater than 0): 0", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMultiANewArrayInsn_tooManyDimensions() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitMultiANewArrayInsn = () -> checkMethodAdapter.visitMultiANewArrayInsn("[[I", 3);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitMultiANewArrayInsn);
+ assertEquals(
+ "Invalid dimensions (must not be greater than numDimensions(descriptor)): 3",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitInsnAnnotation_invalidTypeReference() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitInsnAnnotation =
+ () ->
+ checkMethodAdapter.visitInsnAnnotation(
+ TypeReference.newSuperTypeReference(0).getValue(), null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitInsnAnnotation);
+ assertEquals("Invalid type reference sort 0x10", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTryCatchBlock_afterStartLabel() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(label0);
+
+ Executable visitTryCatchBlock =
+ () -> checkMethodAdapter.visitTryCatchBlock(label0, label1, label1, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitTryCatchBlock);
+ assertEquals("Try catch blocks must be visited before their labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTryCatchBlock_afterEndLabel() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(label0);
+
+ Executable visitTryCatchBlock =
+ () -> checkMethodAdapter.visitTryCatchBlock(label1, label0, label1, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitTryCatchBlock);
+ assertEquals("Try catch blocks must be visited before their labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTryCatchBlock_afterHandlerLabel() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(label0);
+
+ Executable visitTryCatchBlock =
+ () -> checkMethodAdapter.visitTryCatchBlock(label1, label1, label0, null);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitTryCatchBlock);
+ assertEquals("Try catch blocks must be visited before their labels", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTryCatchAnnotation_invalidTypeReference() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitTryCatchAnnotation =
+ () ->
+ checkMethodAdapter.visitTryCatchAnnotation(
+ TypeReference.newSuperTypeReference(0).getValue(), null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTryCatchAnnotation);
+ assertEquals("Invalid type reference sort 0x10", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariable_invalidRange() {
+ Label startLabel = new Label();
+ Label endLabel = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(startLabel);
+ checkMethodAdapter.visitInsn(NOP);
+ checkMethodAdapter.visitLabel(endLabel);
+
+ Executable visitLocalVariable =
+ () -> checkMethodAdapter.visitLocalVariable("i", "I", null, endLabel, startLabel, 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLocalVariable);
+ assertEquals(
+ "Invalid start and end labels (end must be greater than start)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_invalidTypeReference() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.newSuperTypeReference(0).getValue(),
+ null,
+ new Label[0],
+ new Label[0],
+ new int[0],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals("Invalid type reference sort 0x10", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_nullStart_noEnd_noIndex() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.LOCAL_VARIABLE << 24,
+ null,
+ null,
+ new Label[0],
+ new int[0],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals(
+ "Invalid start, end and index arrays (must be non null and of identical length",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_noStart_nullEnd_noIndex() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.LOCAL_VARIABLE << 24,
+ null,
+ new Label[0],
+ null,
+ new int[0],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals(
+ "Invalid start, end and index arrays (must be non null and of identical length",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_noStart_oneNullEnd_noIndex() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.LOCAL_VARIABLE << 24,
+ null,
+ new Label[0],
+ new Label[1],
+ new int[0],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals(
+ "Invalid start, end and index arrays (must be non null and of identical length",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_noStart_noEnd_oneIndex() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.RESOURCE_VARIABLE << 24,
+ null,
+ new Label[0],
+ new Label[0],
+ new int[1],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals(
+ "Invalid start, end and index arrays (must be non null and of identical length",
+ exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_invalidRange() {
+ Label startLabel = new Label();
+ Label endLabel = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitLabel(startLabel);
+ checkMethodAdapter.visitInsn(NOP);
+ checkMethodAdapter.visitLabel(endLabel);
+
+ Executable visitLocalVariableAnnotation =
+ () ->
+ checkMethodAdapter.visitLocalVariableAnnotation(
+ TypeReference.RESOURCE_VARIABLE << 24,
+ null,
+ new Label[] {endLabel},
+ new Label[] {startLabel},
+ new int[1],
+ "LA;",
+ true);
+
+ Exception exception =
+ assertThrows(IllegalArgumentException.class, visitLocalVariableAnnotation);
+ assertEquals(
+ "Invalid start and end labels (end must be greater than start)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitLineNumber_beforeLabel() {
+ checkMethodAdapter.visitCode();
+
+ Executable visitLineNumber = () -> checkMethodAdapter.visitLineNumber(0, new Label());
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitLineNumber);
+ assertEquals("Invalid start label (must be visited first)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMaxs_unvisitedJumpLabels() {
+ Label label = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitJumpInsn(IFEQ, label);
+
+ Executable visitMaxs = () -> checkMethodAdapter.visitMaxs(0, 0);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitMaxs);
+ assertEquals("Undefined label used", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMaxs_unvisitedTryCatchLabels() {
+ Label startLabel = new Label();
+ Label endLabel = new Label();
+ Label handlerLabel = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitTryCatchBlock(startLabel, endLabel, handlerLabel, "E");
+ checkMethodAdapter.visitLabel(endLabel);
+ checkMethodAdapter.visitLabel(handlerLabel);
+
+ Executable visitMaxs = () -> checkMethodAdapter.visitMaxs(0, 0);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitMaxs);
+ assertEquals("Undefined label used", exception.getMessage());
+ }
+
+ @Test
+ void testVisitMaxs_invalidTryCatchRange() {
+ Label startLabel = new Label();
+ Label endLabel = new Label();
+ Label handlerLabel = new Label();
+ checkMethodAdapter.visitCode();
+ checkMethodAdapter.visitTryCatchBlock(endLabel, startLabel, handlerLabel, "E");
+ checkMethodAdapter.visitLabel(startLabel);
+ checkMethodAdapter.visitInsn(NOP);
+ checkMethodAdapter.visitLabel(endLabel);
+ checkMethodAdapter.visitLabel(handlerLabel);
+
+ Executable visitMaxs = () -> checkMethodAdapter.visitMaxs(0, 0);
+
+ Exception exception = assertThrows(IllegalStateException.class, visitMaxs);
+ assertEquals("Empty try catch block handler range", exception.getMessage());
+ }
+
+ @Test
+ void testVisitEnd_invalidDataFlow() {
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", null, new HashMap<>());
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitVarInsn(ASTORE, 0);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(0, 0);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith(
+ "Error at instruction 1: Expected an object reference or a return address, but"
+ + " found I m(I)I"));
+ }
+
+ @Test
+ void testVisitEnd_noInvalidMaxStackIfClassWriterWithComputeMaxs() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ MethodVisitor methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ /* latest api = */ Opcodes.ASM9,
+ /* version = */ Opcodes.V1_5,
+ classWriter,
+ new MethodVisitor(/* latest api = */ Opcodes.ASM9) {});
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", methodVisitor, new HashMap<>());
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(0, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ assertDoesNotThrow(visitEnd);
+ }
+
+ @Test
+ void testVisitEnd_noInvalidMaxStackIfClassWriterWithComputeFrames() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ MethodVisitor methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ /* latest api = */ Opcodes.ASM9,
+ /* version = */ Opcodes.V1_5,
+ classWriter,
+ new MethodVisitor(/* latest api = */ Opcodes.ASM9) {});
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", methodVisitor, new HashMap<>());
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(0, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ assertDoesNotThrow(visitEnd);
+ }
+
+ @Test
+ void testVisitEnd_invalidMaxStackIfClassWriterWithoutComputeMaxsOrComputeFrames() {
+ ClassWriter classWriter = new ClassWriter(0);
+ MethodVisitor methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ /* latest api = */ Opcodes.ASM9,
+ /* version = */ Opcodes.V1_5,
+ classWriter,
+ new MethodVisitor(/* latest api = */ Opcodes.ASM9) {});
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", methodVisitor, new HashMap<>());
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(0, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith("Error at instruction 0: Insufficient maximum stack size. m(I)I"));
+ }
+
+ @Test
+ void testVisitEnd_noMissingFrameIfClassWriterWithComputeFrames() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ MethodVisitor methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ /* latest api = */ Opcodes.ASM9,
+ /* version = */ Opcodes.V1_7,
+ classWriter,
+ new MethodVisitor(/* latest api = */ Opcodes.ASM9) {});
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", methodVisitor, new HashMap<>());
+ Label label = new Label();
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitJumpInsn(IFEQ, label);
+ dataFlowCheckMethodAdapter.visitLabel(label);
+ dataFlowCheckMethodAdapter.visitInsn(ICONST_0);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(1, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ assertDoesNotThrow(visitEnd);
+ }
+
+ @Test
+ void testVisitEnd_missingFrameIfClassWriterWithoutComputeFrames() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ MethodVisitor methodVisitor =
+ new CheckMethodAdapter.MethodWriterWrapper(
+ /* latest api = */ Opcodes.ASM9,
+ /* version = */ Opcodes.V1_7,
+ classWriter,
+ new MethodVisitor(/* latest api = */ Opcodes.ASM9) {});
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)I", methodVisitor, new HashMap<>());
+ Label label = new Label();
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitJumpInsn(IFEQ, label);
+ dataFlowCheckMethodAdapter.visitLabel(label);
+ dataFlowCheckMethodAdapter.visitInsn(ICONST_0);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(1, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith("Error at instruction 1: Expected stack map frame at instruction 2 m(I)I"));
+ }
+
+ @Test
+ void testVisitEnd_invalidReturnType() {
+ MethodVisitor dataFlowCheckMethodAdapter =
+ new CheckMethodAdapter(ACC_PUBLIC, "m", "(I)V", null, new HashMap<>());
+ dataFlowCheckMethodAdapter.visitCode();
+ dataFlowCheckMethodAdapter.visitVarInsn(ILOAD, 1);
+ dataFlowCheckMethodAdapter.visitInsn(IRETURN);
+ dataFlowCheckMethodAdapter.visitMaxs(1, 2);
+
+ Executable visitEnd = () -> dataFlowCheckMethodAdapter.visitEnd();
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitEnd);
+ assertTrue(
+ exception
+ .getMessage()
+ .startsWith(
+ "Error at instruction 1: Incompatible return type: expected null, but found I"
+ + " m(I)V"));
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckModuleAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckModuleAdapterTest.java
new file mode 100644
index 00000000..61b985da
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckModuleAdapterTest.java
@@ -0,0 +1,179 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link CheckModuleAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckModuleAdapterTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new CheckModuleAdapter(null, /* open = */ false));
+ assertThrows(
+ IllegalStateException.class, () -> new CheckModuleAdapter(null, /* open = */ false) {});
+ }
+
+ @Test // see issue #317804
+ void testVisitRequire_javaBaseTransitive() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.classVersion = Opcodes.V10;
+
+ Executable visitRequire =
+ () -> checkModuleAdapter.visitRequire("java.base", Opcodes.ACC_TRANSITIVE, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitRequire);
+ assertEquals(
+ "Invalid access flags: 32 java.base can not be declared ACC_TRANSITIVE or ACC_STATIC_PHASE",
+ exception.getMessage());
+ }
+
+ @Test // see issue #317804
+ void testVisitRequire_javaBaseStaticPhase() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.classVersion = Opcodes.V10;
+
+ Executable visitRequire =
+ () -> checkModuleAdapter.visitRequire("java.base", Opcodes.ACC_STATIC_PHASE, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitRequire);
+ assertEquals(
+ "Invalid access flags: 64 java.base can not be declared ACC_TRANSITIVE or ACC_STATIC_PHASE",
+ exception.getMessage());
+ }
+
+ @Test // see issue #317804
+ void testVisitRequire_javaBaseTransitiveAndStaticPhase() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.classVersion = Opcodes.V10;
+
+ Executable visitRequire =
+ () ->
+ checkModuleAdapter.visitRequire(
+ "java.base", Opcodes.ACC_TRANSITIVE | Opcodes.ACC_STATIC_PHASE, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitRequire);
+ assertEquals(
+ "Invalid access flags: 96 java.base can not be declared ACC_TRANSITIVE or ACC_STATIC_PHASE",
+ exception.getMessage());
+ }
+
+ @Test // see issue #317804
+ void testVisitRequire_javaBaseTransitiveOrStaticPhaseAreIgnoredUnderJvms9() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.classVersion = Opcodes.V9;
+
+ Executable visitRequire =
+ () ->
+ checkModuleAdapter.visitRequire(
+ "java.base", Opcodes.ACC_TRANSITIVE | Opcodes.ACC_STATIC_PHASE, null);
+
+ assertDoesNotThrow(visitRequire);
+ }
+
+ @Test
+ void testVisitExport_nullArray() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+
+ Executable visitExport = () -> checkModuleAdapter.visitExport("package", 0, (String[]) null);
+
+ assertDoesNotThrow(visitExport);
+ }
+
+ @Test
+ void testVisitOpen_nullArray() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+
+ Executable visitOpen = () -> checkModuleAdapter.visitOpen("package", 0, (String[]) null);
+
+ assertDoesNotThrow(visitOpen);
+ }
+
+ @Test
+ void testVisitOpen_openModule() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ true);
+
+ Executable visitOpen = () -> checkModuleAdapter.visitOpen("package", 0, (String[]) null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitOpen);
+ assertEquals("An open module can not use open directive", exception.getMessage());
+ }
+
+ @Test
+ void testVisitUse_nameAlreadyDeclared() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.visitUse("service");
+
+ Executable visitUse = () -> checkModuleAdapter.visitUse("service");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitUse);
+ assertEquals("Module uses 'service' already declared", exception.getMessage());
+ }
+
+ @Test
+ void testVisitUse_afterEnd() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+ checkModuleAdapter.visitEnd();
+
+ Executable visitUse = () -> checkModuleAdapter.visitUse("service");
+
+ Exception exception = assertThrows(IllegalStateException.class, visitUse);
+ assertEquals(
+ "Cannot call a visit method after visitEnd has been called", exception.getMessage());
+ }
+
+ @Test
+ void testVisitProvide_nullProviderList() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+
+ Executable visitProvide = () -> checkModuleAdapter.visitProvide("service2", (String[]) null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitProvide);
+ assertEquals("Providers cannot be null or empty", exception.getMessage());
+ }
+
+ @Test
+ void testVisitProvide_emptyProviderList() {
+ CheckModuleAdapter checkModuleAdapter = new CheckModuleAdapter(null, /* open = */ false);
+
+ Executable visitProvide = () -> checkModuleAdapter.visitProvide("service1");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitProvide);
+ assertEquals("Providers cannot be null or empty", exception.getMessage());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckRecordComponentAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckRecordComponentAdapterTest.java
new file mode 100644
index 00000000..d406701b
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckRecordComponentAdapterTest.java
@@ -0,0 +1,86 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.TypeReference;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link CheckRecordComponentAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckRecordComponentAdapterTest extends AsmTest {
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new CheckRecordComponentAdapter(null));
+ assertThrows(IllegalStateException.class, () -> new CheckRecordComponentAdapter(null) {});
+ }
+
+ @Test
+ void testVisitTypeAnnotation_illegalTypeAnnotation() {
+ CheckRecordComponentAdapter checkRecordComponentAdapter = new CheckRecordComponentAdapter(null);
+
+ Executable visitTypeAnnotation =
+ () ->
+ checkRecordComponentAdapter.visitTypeAnnotation(
+ TypeReference.newFormalParameterReference(0).getValue(), null, "LA;", true);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeAnnotation);
+ assertEquals("Invalid type reference sort 0x16", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_illegalAttribute() {
+ CheckRecordComponentAdapter checkRecordComponentAdapter = new CheckRecordComponentAdapter(null);
+
+ Executable visitAttribute = () -> checkRecordComponentAdapter.visitAttribute(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitAttribute);
+ assertEquals("Invalid attribute (must not be null)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitAttribute_afterEnd() {
+ CheckRecordComponentAdapter checkRecordComponentAdapter = new CheckRecordComponentAdapter(null);
+ checkRecordComponentAdapter.visitEnd();
+
+ Executable visitAttribute = () -> checkRecordComponentAdapter.visitAttribute(new Comment());
+
+ Exception exception = assertThrows(IllegalStateException.class, visitAttribute);
+ assertEquals(
+ "Cannot call a visit method after visitEnd has been called", exception.getMessage());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckSignatureAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckSignatureAdapterTest.java
new file mode 100644
index 00000000..95cb8e8c
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckSignatureAdapterTest.java
@@ -0,0 +1,525 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+import org.objectweb.asm.signature.SignatureWriter;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link CheckSignatureAdapter}.
+ *
+ * @author Eric Bruneton
+ */
+class CheckSignatureAdapterTest extends AsmTest {
+
+ @Test
+ void testVisitFormalTypeParameter_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+ checkSignatureAdapter.visitSuperclass();
+
+ Executable visitFormalTypeParameter = () -> checkSignatureAdapter.visitFormalTypeParameter("T");
+
+ assertThrows(IllegalStateException.class, visitFormalTypeParameter);
+ }
+
+ @Test
+ void testVisitFormalTypeParameter_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitFormalTypeParameter = () -> checkSignatureAdapter.visitFormalTypeParameter("T");
+
+ assertThrows(IllegalStateException.class, visitFormalTypeParameter);
+ }
+
+ @Test
+ void testVisitClassBound_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitClassBound = () -> checkSignatureAdapter.visitClassBound();
+
+ assertThrows(IllegalStateException.class, visitClassBound);
+ }
+
+ @Test
+ void testVisitClassBound_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitClassBound = () -> checkSignatureAdapter.visitClassBound();
+
+ assertThrows(IllegalStateException.class, visitClassBound);
+ }
+
+ @Test
+ void testVisitInterfaceBound_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitInterfaceBound = () -> checkSignatureAdapter.visitInterfaceBound();
+
+ assertThrows(IllegalStateException.class, visitInterfaceBound);
+ }
+
+ @Test
+ void testVisitInterfaceBound_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitInterfaceBound = () -> checkSignatureAdapter.visitInterfaceBound();
+
+ assertThrows(IllegalStateException.class, visitInterfaceBound);
+ }
+
+ @Test
+ void testVisitSuperClass_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+ checkSignatureAdapter.visitSuperclass();
+
+ Executable visitSuperClass = () -> checkSignatureAdapter.visitSuperclass();
+
+ assertThrows(IllegalStateException.class, visitSuperClass);
+ }
+
+ @Test
+ void testVisitSuperClass_methodSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null);
+
+ Executable visitSuperClass = () -> checkSignatureAdapter.visitSuperclass();
+
+ assertThrows(IllegalStateException.class, visitSuperClass);
+ }
+
+ @Test
+ void testVisitInterface_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitInterface = () -> checkSignatureAdapter.visitInterface();
+
+ assertThrows(IllegalStateException.class, visitInterface);
+ }
+
+ @Test
+ void testVisitInterface_methodSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null);
+
+ Executable visitInterface = () -> checkSignatureAdapter.visitInterface();
+
+ assertThrows(IllegalStateException.class, visitInterface);
+ }
+
+ @Test
+ void testVisitParameterType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitParameterType = () -> checkSignatureAdapter.visitParameterType();
+
+ assertThrows(IllegalStateException.class, visitParameterType);
+ }
+
+ @Test
+ void testVisitParameterType_methodSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null);
+ checkSignatureAdapter.visitReturnType();
+
+ Executable visitParameterType = () -> checkSignatureAdapter.visitParameterType();
+
+ assertThrows(IllegalStateException.class, visitParameterType);
+ }
+
+ @Test
+ void testVisitReturnType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitReturnType = () -> checkSignatureAdapter.visitReturnType();
+
+ assertThrows(IllegalStateException.class, visitReturnType);
+ }
+
+ @Test
+ void testVisitReturnType_methodSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null);
+ checkSignatureAdapter.visitReturnType();
+
+ Executable visitReturnType = () -> checkSignatureAdapter.visitReturnType();
+
+ assertThrows(IllegalStateException.class, visitReturnType);
+ }
+
+ @Test
+ void testVisitExceptionType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitExceptionType = () -> checkSignatureAdapter.visitExceptionType();
+
+ assertThrows(IllegalStateException.class, visitExceptionType);
+ }
+
+ @Test
+ void testVisitExceptionType_methodSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null);
+
+ Executable visitExceptionType = () -> checkSignatureAdapter.visitExceptionType();
+
+ assertThrows(IllegalStateException.class, visitExceptionType);
+ }
+
+ @Test
+ void testVisitBaseType_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+ checkSignatureAdapter.visitBaseType('I');
+
+ Executable visitBaseType = () -> checkSignatureAdapter.visitBaseType('I');
+
+ assertThrows(IllegalStateException.class, visitBaseType);
+ }
+
+ @Test
+ void testVisitBaseType_typeSignature_illegalVoidArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitBaseType = () -> checkSignatureAdapter.visitBaseType('V');
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitBaseType);
+ assertEquals("Base type descriptor can't be V", exception.getMessage());
+ }
+
+ @Test
+ void testVisitBaseType_typeSignature_illegalArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitBaseType = () -> checkSignatureAdapter.visitBaseType('A');
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitBaseType);
+ assertEquals("Base type descriptor must be one of ZCBSIFJD", exception.getMessage());
+ }
+
+ @Test
+ void testVisitBaseType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitBaseType = () -> checkSignatureAdapter.visitBaseType('I');
+
+ assertThrows(IllegalStateException.class, visitBaseType);
+ }
+
+ @Test
+ void testVisitTypeVariable_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitTypeVariable = () -> checkSignatureAdapter.visitTypeVariable("T");
+
+ assertThrows(IllegalStateException.class, visitTypeVariable);
+ }
+
+ @Test
+ void testVisitTypeVariable_typeSignature_nullArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitTypeVariable = () -> checkSignatureAdapter.visitTypeVariable(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeVariable);
+ assertEquals("Invalid type variable (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTypeVariable_typeSignature_emptyArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitTypeVariable = () -> checkSignatureAdapter.visitTypeVariable("");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeVariable);
+ assertEquals("Invalid type variable (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTypeVariable_typeSignature_illegalArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitTypeVariable = () -> checkSignatureAdapter.visitTypeVariable("LT;");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeVariable);
+ assertEquals(
+ "Invalid type variable (must not contain . ; [ / < > or :): LT;", exception.getMessage());
+ }
+
+ @Test
+ void testVisitTypeVariable_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+ checkSignatureAdapter.visitTypeVariable("T");
+
+ Executable visitTypeVariable = () -> checkSignatureAdapter.visitTypeVariable("T");
+
+ assertThrows(IllegalStateException.class, visitTypeVariable);
+ }
+
+ @Test
+ void testVisitArrayType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitArrayType = () -> checkSignatureAdapter.visitArrayType();
+
+ assertThrows(IllegalStateException.class, visitArrayType);
+ }
+
+ @Test
+ void testVisitArrayType_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+ checkSignatureAdapter.visitArrayType();
+
+ Executable visitArrayType = () -> checkSignatureAdapter.visitArrayType();
+
+ assertThrows(IllegalStateException.class, visitArrayType);
+ }
+
+ @Test
+ void testVisitClassType_classSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+
+ Executable visitClassType = () -> checkSignatureAdapter.visitClassType("A");
+
+ assertThrows(IllegalStateException.class, visitClassType);
+ }
+
+ @Test
+ void testVisitClassType_typeSignature_nullArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitClassType = () -> checkSignatureAdapter.visitClassType(null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitClassType);
+ assertEquals("Invalid class name (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitClassType_typeSignature_emptyArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitClassType = () -> checkSignatureAdapter.visitClassType("");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitClassType);
+ assertEquals("Invalid class name (must not be null or empty)", exception.getMessage());
+ }
+
+ @Test
+ void testVisitClassType_typeSignature_illegalArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitClassType = () -> checkSignatureAdapter.visitClassType("<A>");
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitClassType);
+ assertEquals(
+ "Invalid class name (must not contain . ; [ < > or :): <A>", exception.getMessage());
+ }
+
+ @Test
+ void testVisitClassType_typeSignature_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+ checkSignatureAdapter.visitClassType("A");
+
+ Executable visitClassType = () -> checkSignatureAdapter.visitClassType("A");
+
+ assertThrows(IllegalStateException.class, visitClassType);
+ }
+
+ @Test
+ void testVisitClassType_nonJavaIdentifier() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null);
+ SignatureVisitor signatureVisitor = checkSignatureAdapter.visitSuperclass();
+
+ Executable visitClassType = () -> signatureVisitor.visitClassType("Foo Bar");
+
+ assertDoesNotThrow(visitClassType);
+ }
+
+ @Test
+ void testVisitInnerClassType_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitInnerClassType = () -> checkSignatureAdapter.visitInnerClassType("A");
+
+ assertThrows(IllegalStateException.class, visitInnerClassType);
+ }
+
+ @Test
+ void testVisitTypeArgument_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitTypeArgument = () -> checkSignatureAdapter.visitTypeArgument();
+
+ assertThrows(IllegalStateException.class, visitTypeArgument);
+ }
+
+ @Test
+ void testVisitTypeArgument_wildcard_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitTypeArgument = () -> checkSignatureAdapter.visitTypeArgument('+');
+
+ assertThrows(IllegalStateException.class, visitTypeArgument);
+ }
+
+ @Test
+ void testVisitTypeArgument_wildcard_illegalArgument() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+ checkSignatureAdapter.visitClassType("A");
+
+ Executable visitTypeArgument = () -> checkSignatureAdapter.visitTypeArgument('*');
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitTypeArgument);
+ assertEquals("Wildcard must be one of +-=", exception.getMessage());
+ }
+
+ @Test
+ void testVisitEnd_illegalState() {
+ CheckSignatureAdapter checkSignatureAdapter =
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null);
+
+ Executable visitEnd = () -> checkSignatureAdapter.visitEnd();
+
+ assertThrows(IllegalStateException.class, visitEnd);
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#classSignatures"})
+ void testVisitMethods_classSignature(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureWriter signatureWriter = new SignatureWriter();
+
+ signatureReader.accept(
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, signatureWriter));
+
+ assertEquals(signature, signatureWriter.toString());
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#classSignatures"})
+ void testVisitMethods_classSignature_noDelegate(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+
+ Executable visitMethods =
+ () ->
+ signatureReader.accept(
+ new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, null));
+
+ assertDoesNotThrow(visitMethods);
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#methodSignatures"})
+ void testVisitMethods_methodSignature(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureWriter signatureWriter = new SignatureWriter();
+
+ signatureReader.accept(
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, signatureWriter));
+
+ assertEquals(signature, signatureWriter.toString());
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#methodSignatures"})
+ void testVisitMethods_methodSignature_noDelegate(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+
+ Executable visitMethods =
+ () ->
+ signatureReader.accept(
+ new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, null));
+
+ assertDoesNotThrow(visitMethods);
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#fieldSignatures"})
+ void testVisitMethods_typeSignature(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureWriter signatureWriter = new SignatureWriter();
+
+ signatureReader.acceptType(
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, signatureWriter));
+
+ assertEquals(signature, signatureWriter.toString());
+ }
+
+ @ParameterizedTest
+ @MethodSource({"org.objectweb.asm.util.SignaturesProviders#fieldSignatures"})
+ void testVisitMethods_typeSignature_noDelegate(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+
+ Executable visitMethods =
+ () ->
+ signatureReader.acceptType(
+ new CheckSignatureAdapter(CheckSignatureAdapter.TYPE_SIGNATURE, null));
+
+ assertDoesNotThrow(visitMethods);
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java b/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java
new file mode 100644
index 00000000..86ffe56c
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/CodeComment.java
@@ -0,0 +1,92 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.Map;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard code attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class CodeComment extends Attribute implements ASMifierSupport, TextifierSupport {
+
+ public CodeComment() {
+ super("CodeComment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new CodeComment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+
+ @Override
+ public void asmify(
+ final StringBuilder stringBuilder,
+ final String varName,
+ final Map<Label, String> labelNames) {
+ stringBuilder
+ .append("Attribute ")
+ .append(varName)
+ .append(" = new org.objectweb.asm.util.CodeComment();");
+ }
+
+ @Override
+ public void textify(final StringBuilder stringBuilder, final Map<Label, String> labelNames) {}
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/Comment.java b/asm-util/src/test/java/org/objectweb/asm/util/Comment.java
new file mode 100644
index 00000000..31bbb2c6
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/Comment.java
@@ -0,0 +1,92 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.Map;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * A non standard attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class Comment extends Attribute implements ASMifierSupport, TextifierSupport {
+
+ public Comment() {
+ super("Comment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new Comment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+
+ @Override
+ public void asmify(
+ final StringBuilder stringBuilder,
+ final String varName,
+ final Map<Label, String> labelNames) {
+ stringBuilder
+ .append("Attribute ")
+ .append(varName)
+ .append(" = new org.objectweb.asm.util.Comment();");
+ }
+
+ @Override
+ public void textify(final StringBuilder stringBuilder, final Map<Label, String> labelNames) {}
+
+ @Override
+ public String toString() {
+ return "CommentAttribute";
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/MethodNodeBuilder.java b/asm-util/src/test/java/org/objectweb/asm/util/MethodNodeBuilder.java
new file mode 100644
index 00000000..936d4ce9
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/MethodNodeBuilder.java
@@ -0,0 +1,109 @@
+// ASM: a very sm14all and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import java.util.Arrays;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.FrameNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * A builder of {@link MethodNode}, to construct test cases for unit tests.
+ *
+ * @author Eric Bruneton
+ */
+final class MethodNodeBuilder {
+
+ private final MethodNode methodNode;
+
+ MethodNodeBuilder() {
+ this(/* maxStack = */ 10, /* maxLocals = */ 10);
+ }
+
+ MethodNodeBuilder(final int maxStack, final int maxLocals) {
+ methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ methodNode.maxStack = maxStack;
+ methodNode.maxLocals = maxLocals;
+ methodNode.visitCode();
+ }
+
+ MethodNodeBuilder nop() {
+ methodNode.visitInsn(Opcodes.NOP);
+ return this;
+ }
+
+ MethodNodeBuilder iconst_0() {
+ methodNode.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ MethodNodeBuilder vreturn() {
+ methodNode.visitInsn(Opcodes.RETURN);
+ return this;
+ }
+
+ MethodNodeBuilder label(final Label label) {
+ methodNode.visitLabel(label);
+ return this;
+ }
+
+ MethodNodeBuilder go(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.GOTO, label);
+ return this;
+ }
+
+ MethodNodeBuilder jsr(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.JSR, label);
+ return this;
+ }
+
+ MethodNodeBuilder ret(final int varIndex) {
+ methodNode.visitVarInsn(Opcodes.RET, varIndex);
+ return this;
+ }
+
+ MethodNodeBuilder ifne(final Label label) {
+ methodNode.visitJumpInsn(Opcodes.IFNE, label);
+ return this;
+ }
+
+ MethodNodeBuilder frame(final int type, final Object[] local, final Object[] stack) {
+ FrameNode frameNode = new FrameNode(Opcodes.F_NEW, 0, null, 0, null);
+ frameNode.type = type;
+ frameNode.local = local == null ? null : Arrays.asList(local);
+ frameNode.stack = stack == null ? null : Arrays.asList(stack);
+ methodNode.instructions.add(frameNode);
+ return this;
+ }
+
+ MethodNode build() {
+ methodNode.visitEnd();
+ return methodNode;
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java
new file mode 100644
index 00000000..0905eb76
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java
@@ -0,0 +1,541 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link Printer}.
+ *
+ * @author Eric Bruneton
+ */
+class PrinterTest {
+
+ private static final String UNSUPPORTED_OPERATION_MESSAGE = "Must be overridden";
+
+ @Test
+ void testVisitModule_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitModule = () -> printer.visitModule(null, 0, null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitModule);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitNestHost_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitNestHost = () -> printer.visitNestHost(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitNestHost);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitClassTypeAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitClassTypeAnnotation =
+ () -> printer.visitClassTypeAnnotation(0, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitClassTypeAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitNestMember_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitNestMember = () -> printer.visitNestMember(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitNestMember);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitPermittedSubclass_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitPermittedSubclass = () -> printer.visitPermittedSubclass(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitPermittedSubclass);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMainClass_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitMainClass = () -> printer.visitMainClass(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMainClass);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitPackage_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitPackage = () -> printer.visitPackage(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitPackage);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitRequire_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitRequire = () -> printer.visitRequire(null, 0, null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitRequire);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitExport_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitExport = () -> printer.visitExport(null, 0);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitExport);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitOpen_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitOpen = () -> printer.visitOpen(null, 0);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitOpen);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitUse_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitUse = () -> printer.visitUse(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitUse);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitProvide_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitProvide = () -> printer.visitProvide(null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitProvide);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitModuleEnd_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitModuleEnd = () -> printer.visitModuleEnd();
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitModuleEnd);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitFieldTypeAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitFieldTypeAnnotation =
+ () -> printer.visitFieldTypeAnnotation(0, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitFieldTypeAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitParameter_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitParameter = () -> printer.visitParameter(null, 0);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitParameter);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodTypeAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitMethodTypeAnnotation =
+ () -> printer.visitMethodTypeAnnotation(0, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitMethodTypeAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitAnnotableParameterCount_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitAnnotableParameterCount = () -> printer.visitAnnotableParameterCount(0, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitAnnotableParameterCount);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_asm4_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(Opcodes.ASM4);
+
+ Executable visitMethodInsn =
+ () -> printer.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", false);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMethodInsn);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitMethodInsn =
+ () -> printer.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", false);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMethodInsn);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitMethodInsn_ifItf_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitMethodInsn =
+ () -> printer.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", true);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMethodInsn);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitInsnAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitInsnAnnotation = () -> printer.visitInsnAnnotation(0, null, null, false);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitInsnAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitTryCatchAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitTryCatchAnnotation =
+ () -> printer.visitTryCatchAnnotation(0, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitTryCatchAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_unsupportedByDefault() {
+ Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+
+ Executable visitLocalVariableAnnotation =
+ () -> printer.visitLocalVariableAnnotation(0, null, null, null, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitLocalVariableAnnotation);
+ assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage());
+ }
+
+ static class EmptyPrinter extends Printer {
+
+ EmptyPrinter(final int api) {
+ super(api);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitSource(final String source, final String debug) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ // Do nothing.
+ }
+
+ @Override
+ public Printer visitClassAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public void visitClassAttribute(final Attribute attribute) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ // Do nothing.
+ }
+
+ @Override
+ public Printer visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return null;
+ }
+
+ @Override
+ public Printer visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return null;
+ }
+
+ @Override
+ public void visitClassEnd() {
+ // Do nothing.
+ }
+
+ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
+ @Override
+ public void visit(final String name, final Object value) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ // Do nothing.
+ }
+
+ @Override
+ public Printer visitAnnotation(final String name, final String descriptor) {
+ return null;
+ }
+
+ @Override
+ public Printer visitArray(final String name) {
+ return null;
+ }
+
+ @Override
+ public void visitAnnotationEnd() {
+ // Do nothing.
+ }
+
+ @Override
+ public Printer visitFieldAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public void visitFieldAttribute(final Attribute attribute) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitFieldEnd() {
+ // Do nothing.
+ }
+
+ @Override
+ public Printer visitAnnotationDefault() {
+ return null;
+ }
+
+ @Override
+ public Printer visitMethodAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public Printer visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public void visitMethodAttribute(final Attribute attribute) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitCode() {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ // Do nothing.
+ }
+
+ @Override
+ public void visitMethodEnd() {
+ // Do nothing.
+ }
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java b/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java
new file mode 100644
index 00000000..fdc28a1d
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java
@@ -0,0 +1,96 @@
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.AsmTest.PrecompiledClass;
+
+/**
+ * Provides class, field and method signatures for parameterized unit tests.
+ *
+ * @author Eric Bruneton
+ */
+public final class SignaturesProviders {
+
+ private static final List<String> CLASS_SIGNATURES = new ArrayList<>();
+ private static final List<String> FIELD_SIGNATURES = new ArrayList<>();
+ private static final List<String> METHOD_SIGNATURES = new ArrayList<>();
+
+ static {
+ AsmTest.allClassesAndLatestApi()
+ .map(argument -> (PrecompiledClass) argument.get()[0])
+ .filter(precompiledClass -> !precompiledClass.isMoreRecentThan(AsmTest.Api.ASM7))
+ .forEach(precompiledClass -> collectSignatures(precompiledClass));
+ assertFalse(CLASS_SIGNATURES.isEmpty());
+ assertFalse(FIELD_SIGNATURES.isEmpty());
+ assertFalse(METHOD_SIGNATURES.isEmpty());
+ }
+
+ private SignaturesProviders() {}
+
+ private static void collectSignatures(final PrecompiledClass classParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ classReader.accept(
+ new ClassVisitor(/* latest api*/ Opcodes.ASM9) {
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if (signature != null) {
+ CLASS_SIGNATURES.add(signature);
+ }
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ if (signature != null) {
+ FIELD_SIGNATURES.add(signature);
+ }
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ if (signature != null) {
+ METHOD_SIGNATURES.add(signature);
+ }
+ return null;
+ }
+ },
+ 0);
+ }
+
+ static Stream<String> classSignatures() {
+ return CLASS_SIGNATURES.stream();
+ }
+
+ static Stream<String> fieldSignatures() {
+ return FIELD_SIGNATURES.stream();
+ }
+
+ static Stream<String> methodSignatures() {
+ return METHOD_SIGNATURES.stream();
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/TextifierTest.java b/asm-util/src/test/java/org/objectweb/asm/util/TextifierTest.java
new file mode 100644
index 00000000..bfbfb92e
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/TextifierTest.java
@@ -0,0 +1,202 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link Textifier}.
+ *
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+class TextifierTest extends AsmTest {
+
+ private static final String EXPECTED_USAGE =
+ "Prints a disassembled view of the given class.\n"
+ + "Usage: Textifier [-nodebug] <fully qualified class name or class file name>";
+
+ @Test
+ void testConstructor() {
+ assertDoesNotThrow(() -> new Textifier());
+ assertThrows(IllegalStateException.class, () -> new Textifier() {});
+ }
+
+ /**
+ * Tests that the text produced with a Textifier is equal to the expected text.
+ *
+ * @throws IOException if the expected text can't be read from disk.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testTextify_precompiledClass(final PrecompiledClass classParameter, final Api apiParameter)
+ throws IOException {
+ byte[] classFile = classParameter.getBytes();
+ StringWriter output = new StringWriter();
+ assumeTrue(classFile.length < 32768);
+
+ new ClassReader(classFile)
+ .accept(
+ new TraceClassVisitor(
+ null, new Textifier(apiParameter.value()) {}, new PrintWriter(output)),
+ 0);
+
+ String expectedText =
+ new String(
+ Files.readAllBytes(
+ Paths.get("src/test/resources/" + classParameter.getName() + ".txt")),
+ StandardCharsets.UTF_8)
+ .replace("\r", "");
+
+ assertEquals(expectedText, output.toString());
+ }
+
+ @Test
+ void testMain_missingClassName() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = new String[0];
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_missingClassName_withNodebug() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug"};
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_tooManyArguments() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug", getClass().getName(), "extraArgument"};
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertEquals("", output.toString());
+ assertEquals(EXPECTED_USAGE, logger.toString().trim());
+ }
+
+ @Test
+ void testMain_classFileNotFound() {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"DoNotExist.class"};
+
+ Executable main =
+ () -> Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", output.toString());
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classNotFound() {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"do\\not\\exist"};
+
+ Executable main =
+ () -> Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertThrows(IOException.class, main);
+ assertEquals("", output.toString());
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_className() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {getClass().getName()};
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("\nclass org/objectweb/asm/util/TextifierTest"));
+ assertTrue(output.toString().contains("\n LINENUMBER"));
+ assertTrue(output.toString().contains("\n LOCALVARIABLE"));
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_className_withNoebug() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {"-nodebug", getClass().getName()};
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("\nclass org/objectweb/asm/util/TextifierTest"));
+ assertFalse(output.toString().contains("\n LINENUMBER"));
+ assertFalse(output.toString().contains("\n LOCALVARIABLE"));
+ assertEquals("", logger.toString());
+ }
+
+ @Test
+ void testMain_classFile() throws IOException {
+ StringWriter output = new StringWriter();
+ StringWriter logger = new StringWriter();
+ String[] args = {
+ ClassLoader.getSystemResource(getClass().getName().replace('.', '/') + ".class").getPath()
+ };
+
+ Textifier.main(args, new PrintWriter(output, true), new PrintWriter(logger, true));
+
+ assertTrue(output.toString().contains("\nclass org/objectweb/asm/util/TextifierTest"));
+ assertEquals("", logger.toString());
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/TraceClassVisitorTest.java b/asm-util/src/test/java/org/objectweb/asm/util/TraceClassVisitorTest.java
new file mode 100644
index 00000000..b3491893
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/TraceClassVisitorTest.java
@@ -0,0 +1,139 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link TraceClassVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class TraceClassVisitorTest extends AsmTest {
+
+ /**
+ * Tests that classes are unchanged with a ClassReader->TraceClassVisitor->ClassWriter transform.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitMethods(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor traceClassVisitor =
+ new TraceClassVisitor(classWriter, new PrintWriter(new StringWriter()));
+
+ classReader.accept(traceClassVisitor, new Attribute[] {new Comment(), new CodeComment()}, 0);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /** Tests that ClassReader can accept a TraceClassVisitor without delegate. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitMethods_noDelegate(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ StringWriter output = new StringWriter();
+
+ classReader.accept(new TraceClassVisitor(new PrintWriter(output, true)), 0);
+
+ assertTrue(output.toString().contains(classParameter.getInternalName()));
+ }
+
+ /**
+ * Tests that ClassReader can accept a TraceAnnotationVisitor, TraceFieldVisitor,
+ * TraceMethodVisitor or TraceModuleVisitor without delegate.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testVisitMethods_noNestedDelegate(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+
+ Executable accept =
+ () ->
+ classReader.accept(
+ new ClassVisitor(apiParameter.value()) {
+
+ @Override
+ public ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ return new TraceModuleVisitor(new Textifier());
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(
+ final String descriptor, final boolean visible) {
+ return new TraceAnnotationVisitor(new Textifier());
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return new TraceFieldVisitor(new Textifier());
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new TraceMethodVisitor(new Textifier());
+ }
+ },
+ 0);
+
+ assertDoesNotThrow(accept);
+ }
+}
diff --git a/asm-util/src/test/java/org/objectweb/asm/util/TraceSignatureVisitorTest.java b/asm-util/src/test/java/org/objectweb/asm/util/TraceSignatureVisitorTest.java
new file mode 100644
index 00000000..4250ebdd
--- /dev/null
+++ b/asm-util/src/test/java/org/objectweb/asm/util/TraceSignatureVisitorTest.java
@@ -0,0 +1,186 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.signature.SignatureReader;
+
+/**
+ * Unit tests for {@link TraceSignatureVisitor}.
+ *
+ * @author Eugene Kuleshov
+ */
+class TraceSignatureVisitorTest {
+
+ private static final String[][] CLASS_SIGNATURES = {
+ {
+ "false",
+ "<E extends java.lang.Enum<E>> implements java.lang.Comparable<E>, java.io.Serializable",
+ "<E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable;"
+ },
+ {
+ "true",
+ "<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type",
+ "<D::Ljava/lang/reflect/GenericDeclaration;>Ljava/lang/Object;Ljava/lang/reflect/Type;"
+ },
+ {
+ "false",
+ "<K, V> extends java.util.AbstractMap<K, V> implements java.util.concurrent.ConcurrentMap<K, V>, java.io.Serializable",
+ "<K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/util/concurrent/ConcurrentMap<TK;TV;>;Ljava/io/Serializable;"
+ },
+ {
+ "false",
+ "<K extends java.lang.Enum<K>, V> extends java.util.AbstractMap<K, V> implements java.io.Serializable, java.lang.Cloneable",
+ "<K:Ljava/lang/Enum<TK;>;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/io/Serializable;Ljava/lang/Cloneable;"
+ },
+ {"false", "<T, R extends T>", "<T:Ljava/lang/Object;R:TT;>Ljava/lang/Object;"}
+ };
+
+ private static final String[][] FIELD_SIGNATURES = {
+ {"T[]", "[TT;"},
+ {"AA<byte[][]>", "LAA<[[B>;"},
+ {"java.lang.Class<?>", "Ljava/lang/Class<*>;"},
+ {"java.lang.reflect.Constructor<T>", "Ljava/lang/reflect/Constructor<TT;>;"},
+ {"java.util.Hashtable<?, ?>", "Ljava/util/Hashtable<**>;"},
+ {
+ "java.util.concurrent.atomic.AtomicReferenceFieldUpdater<java.io.BufferedInputStream, byte[]>",
+ "Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater<Ljava/io/BufferedInputStream;[B>;"
+ },
+ {
+ "AA<java.util.Map<java.lang.String, java.lang.String>[][]>",
+ "LAA<[[Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;>;"
+ },
+ {
+ "java.util.Hashtable<java.lang.Object, java.lang.String>",
+ "Ljava/util/Hashtable<Ljava/lang/Object;Ljava/lang/String;>;"
+ }
+ };
+
+ private static final String[][] METHOD_SIGNATURES = {
+ {"void()E, F", "()V^TE;^TF;"},
+ {"void(A<E>.B)", "(LA<TE;>.B;)V"},
+ {"void(A<E>.B<F>)", "(LA<TE;>.B<TF;>;)V"},
+ {"void(boolean, byte, char, short, int, float, long, double)", "(ZBCSIFJD)V"},
+ {
+ "java.lang.Class<? extends E><E extends java.lang.Class>()",
+ "<E:Ljava/lang/Class;>()Ljava/lang/Class<+TE;>;"
+ },
+ {
+ "java.lang.Class<? super E><E extends java.lang.Class>()",
+ "<E:Ljava/lang/Class;>()Ljava/lang/Class<-TE;>;"
+ },
+ {
+ "void(java.lang.String, java.lang.Class<?>, java.lang.reflect.Method[], java.lang.reflect.Method, java.lang.reflect.Method)",
+ "(Ljava/lang/String;Ljava/lang/Class<*>;[Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V"
+ },
+ {
+ "java.util.Map<java.lang.Object, java.lang.String>(java.lang.Object, java.util.Map<java.lang.Object, java.lang.String>)",
+ "(Ljava/lang/Object;Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;)Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;"
+ },
+ {
+ "java.util.Map<java.lang.Object, java.lang.String><T>(java.lang.Object, java.util.Map<java.lang.Object, java.lang.String>, T)",
+ "<T:Ljava/lang/Object;>(Ljava/lang/Object;Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;TT;)Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;"
+ },
+ {
+ "java.util.Map<java.lang.Object, java.lang.String><E, T extends java.lang.Comparable<E>>(java.lang.Object, java.util.Map<java.lang.Object, java.lang.String>, T)",
+ "<E:Ljava/lang/Object;T::Ljava/lang/Comparable<TE;>;>(Ljava/lang/Object;Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;TT;)Ljava/util/Map<Ljava/lang/Object;Ljava/lang/String;>;"
+ }
+ };
+
+ public static Stream<Arguments> classSignatures() {
+ return Arrays.stream(CLASS_SIGNATURES).map(values -> Arguments.of((Object[]) values));
+ }
+
+ public static Stream<Arguments> fieldSignatures() {
+ return Arrays.stream(FIELD_SIGNATURES).map(values -> Arguments.of((Object[]) values));
+ }
+
+ public static Stream<Arguments> methodSignatures() {
+ return Arrays.stream(METHOD_SIGNATURES).map(values -> Arguments.of((Object[]) values));
+ }
+
+ @Test
+ void testVisitBaseType_invalidSignature() {
+ TraceSignatureVisitor traceSignatureVisitor = new TraceSignatureVisitor(0);
+
+ Executable visitBaseType = () -> traceSignatureVisitor.visitBaseType('-');
+
+ assertThrows(IllegalArgumentException.class, visitBaseType);
+ }
+
+ @ParameterizedTest
+ @MethodSource("classSignatures")
+ void testVisitMethods_classSignature(
+ final boolean isInterface, final String declaration, final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ TraceSignatureVisitor traceSignatureVisitor =
+ new TraceSignatureVisitor(isInterface ? Opcodes.ACC_INTERFACE : 0);
+
+ signatureReader.accept(traceSignatureVisitor);
+
+ assertEquals(declaration, traceSignatureVisitor.getDeclaration());
+ }
+
+ @ParameterizedTest
+ @MethodSource("fieldSignatures")
+ void testVisitMethods_fieldSignature(final String declaration, final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ TraceSignatureVisitor traceSignatureVisitor = new TraceSignatureVisitor(0);
+
+ signatureReader.acceptType(traceSignatureVisitor);
+
+ assertEquals(declaration, traceSignatureVisitor.getDeclaration());
+ }
+
+ @ParameterizedTest
+ @MethodSource("methodSignatures")
+ void testVisitMethods_methodSignature(final String declaration, final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ TraceSignatureVisitor traceSignatureVisitor = new TraceSignatureVisitor(0);
+
+ signatureReader.accept(traceSignatureVisitor);
+
+ String fullMethodDeclaration =
+ traceSignatureVisitor.getReturnType()
+ + traceSignatureVisitor.getDeclaration()
+ + (traceSignatureVisitor.getExceptions() != null
+ ? traceSignatureVisitor.getExceptions()
+ : "");
+ assertEquals(declaration, fullMethodDeclaration);
+ }
+}
diff --git a/asm-util/src/test/resources/DefaultPackage.txt b/asm-util/src/test/resources/DefaultPackage.txt
new file mode 100644
index 00000000..de3acbda
--- /dev/null
+++ b/asm-util/src/test/resources/DefaultPackage.txt
@@ -0,0 +1,6 @@
+// class version 45.0 (45)
+// access flags 0x600
+abstract interface DefaultPackage {
+
+ // compiled from: DefaultPackage.java
+}
diff --git a/asm-util/src/test/resources/jdk11.AllInstructions.txt b/asm-util/src/test/resources/jdk11.AllInstructions.txt
new file mode 100644
index 00000000..e9a961be
--- /dev/null
+++ b/asm-util/src/test/resources/jdk11.AllInstructions.txt
@@ -0,0 +1,57 @@
+// class version 55.0 (55)
+// access flags 0x21
+public class jdk11/AllInstructions {
+
+ // compiled from: AllInstructions.jasm
+ // access flags 0x19
+ public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
+
+ // access flags 0x1
+ public <init>()V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public m()Ljava/lang/Object;
+ LDC name : Ljava/lang/Object; jdk11/HandleOwner.handleField(Ljava/lang/Object;)Ljava/lang/Object; (6) [argumentName : Ljava/lang/Object; jdk11/ArgumentHandleOwner.argumentHandleNameLjava/lang/Object; (2) []]
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static primitiveExample()J
+ LDC test : J jdk11/AllInstructions.bsm(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J (6) []
+ LRETURN
+ MAXSTACK = 2
+ MAXLOCALS = 0
+
+ // access flags 0xA
+ private static bsm(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)J
+ BIPUSH 42
+ I2L
+ LRETURN
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x9
+ public static main([Ljava/lang/String;)V
+ LDC run : Ljava/lang/Runnable; java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/Object; (6) [()V, jdk11/AllInstructions.lambda$main$0()V (6), ()V]
+ ASTORE 1
+ ALOAD 1
+ INVOKEINTERFACE java/lang/Runnable.run ()V (itf)
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 2
+
+ // access flags 0x100A
+ private static synthetic lambda$main$0()V
+ GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
+ LDC "hello condy"
+ INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 0
+}
diff --git a/asm-util/src/test/resources/jdk11.AllStructures$Nested.txt b/asm-util/src/test/resources/jdk11.AllStructures$Nested.txt
new file mode 100644
index 00000000..c7bf3209
--- /dev/null
+++ b/asm-util/src/test/resources/jdk11.AllStructures$Nested.txt
@@ -0,0 +1,15 @@
+// class version 55.0 (55)
+// access flags 0x21
+public class jdk11/AllStructures$Nested {
+
+ // compiled from: AllStructures$Nested.jasm
+ NESTHOST jdk11/AllStructures
+
+ // access flags 0x1
+ public <init>()V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk11.AllStructures.txt b/asm-util/src/test/resources/jdk11.AllStructures.txt
new file mode 100644
index 00000000..9b68bc9c
--- /dev/null
+++ b/asm-util/src/test/resources/jdk11.AllStructures.txt
@@ -0,0 +1,15 @@
+// class version 55.0 (55)
+// access flags 0x21
+public class jdk11/AllStructures {
+
+ // compiled from: AllStructures.jasm
+ NESTMEMBER jdk11/AllStructures$Nested
+
+ // access flags 0x1
+ public <init>()V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk14.AllStructures$EmptyRecord.txt b/asm-util/src/test/resources/jdk14.AllStructures$EmptyRecord.txt
new file mode 100644
index 00000000..b5ea5682
--- /dev/null
+++ b/asm-util/src/test/resources/jdk14.AllStructures$EmptyRecord.txt
@@ -0,0 +1,71 @@
+// class version 58.65535 (-65478)
+// RECORD
+// access flags 0x10030
+final class jdk14/AllStructures$EmptyRecord extends java/lang/Record {
+
+ // compiled from: AllStructures.java
+ NESTHOST jdk14/AllStructures
+ // access flags 0x18
+ final static INNERCLASS jdk14/AllStructures$EmptyRecord jdk14/AllStructures EmptyRecord
+ // access flags 0x19
+ public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
+
+ // access flags 0x1
+ public <init>()V
+ L0
+ LINENUMBER 44 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Record.<init> ()V
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public toString()Ljava/lang/String;
+ L0
+ LINENUMBER 44 L0
+ ALOAD 0
+ INVOKEDYNAMIC toString(Ljdk14/AllStructures$EmptyRecord;)Ljava/lang/String; [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$EmptyRecord.class,
+ ""
+ ]
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x11
+ public final hashCode()I
+ L0
+ LINENUMBER 44 L0
+ ALOAD 0
+ INVOKEDYNAMIC hashCode(Ljdk14/AllStructures$EmptyRecord;)I [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$EmptyRecord.class,
+ ""
+ ]
+ IRETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x11
+ public final equals(Ljava/lang/Object;)Z
+ L0
+ LINENUMBER 44 L0
+ ALOAD 0
+ ALOAD 1
+ INVOKEDYNAMIC equals(Ljdk14/AllStructures$EmptyRecord;Ljava/lang/Object;)Z [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$EmptyRecord.class,
+ ""
+ ]
+ IRETURN
+ MAXSTACK = 2
+ MAXLOCALS = 2
+}
diff --git a/asm-util/src/test/resources/jdk14.AllStructures$RecordSubType.txt b/asm-util/src/test/resources/jdk14.AllStructures$RecordSubType.txt
new file mode 100644
index 00000000..d00f62b6
--- /dev/null
+++ b/asm-util/src/test/resources/jdk14.AllStructures$RecordSubType.txt
@@ -0,0 +1,147 @@
+// class version 58.65535 (-65478)
+// RECORD
+// access flags 0x10030
+final class jdk14/AllStructures$RecordSubType extends java/lang/Record {
+
+ // compiled from: AllStructures.java
+ NESTHOST jdk14/AllStructures
+ // access flags 0x18
+ final static INNERCLASS jdk14/AllStructures$RecordSubType jdk14/AllStructures RecordSubType
+ // access flags 0x19
+ public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
+ RECORDCOMPONENT I component1
+ @Lannotations/VRCA;(v=1)
+ @Lannotations/IRCA;(v=0) // invisible
+ @Lannotations/VTUA;(v=2) : FIELD, null
+ @Lannotations/ITUA;(v=3) : FIELD, null // invisible
+ RECORDCOMPONENT // signature Ljava/util/List<Ljava/lang/String;>;
+ // declaration: component2 extends java.util.List<java.lang.String>
+ Ljava/util/List; component2
+ @Lannotations/VRCA;(v=5)
+ @Lannotations/IRCA;(v=4) // invisible
+ @Lannotations/VTUA;(v=6) : FIELD, null
+ @Lannotations/ITUA;(v=7) : FIELD, null // invisible
+
+ // access flags 0x12
+ private final I component1
+ @Lannotations/VTUA;(v=2) : FIELD, null
+ @Lannotations/ITUA;(v=3) : FIELD, null // invisible
+
+ // access flags 0x12
+ // signature Ljava/util/List<Ljava/lang/String;>;
+ // declaration: component2 extends java.util.List<java.lang.String>
+ private final Ljava/util/List; component2
+ @Lannotations/VTUA;(v=6) : FIELD, null
+ @Lannotations/ITUA;(v=7) : FIELD, null // invisible
+
+ // access flags 0x1
+ // signature (ILjava/util/List<Ljava/lang/String;>;)V
+ // declaration: void <init>(int, java.util.List<java.lang.String>)
+ public <init>(ILjava/util/List;)V
+ // parameter component1
+ // parameter component2
+ @Lannotations/VTUA;(v=2) : METHOD_FORMAL_PARAMETER 0, null
+ @Lannotations/VTUA;(v=6) : METHOD_FORMAL_PARAMETER 1, null
+ @Lannotations/ITUA;(v=3) : METHOD_FORMAL_PARAMETER 0, null // invisible
+ @Lannotations/ITUA;(v=7) : METHOD_FORMAL_PARAMETER 1, null // invisible
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Record.<init> ()V
+ ALOAD 0
+ ILOAD 1
+ PUTFIELD jdk14/AllStructures$RecordSubType.component1 : I
+ ALOAD 0
+ ALOAD 2
+ PUTFIELD jdk14/AllStructures$RecordSubType.component2 : Ljava/util/List;
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public toString()Ljava/lang/String;
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ INVOKEDYNAMIC toString(Ljdk14/AllStructures$RecordSubType;)Ljava/lang/String; [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$RecordSubType.class,
+ "component1;component2",
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component1(I),
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component2(Ljava/util/List;)
+ ]
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x11
+ public final hashCode()I
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ INVOKEDYNAMIC hashCode(Ljdk14/AllStructures$RecordSubType;)I [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$RecordSubType.class,
+ "component1;component2",
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component1(I),
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component2(Ljava/util/List;)
+ ]
+ IRETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x11
+ public final equals(Ljava/lang/Object;)Z
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ ALOAD 1
+ INVOKEDYNAMIC equals(Ljdk14/AllStructures$RecordSubType;Ljava/lang/Object;)Z [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/runtime/ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
+ // arguments:
+ jdk14.AllStructures$RecordSubType.class,
+ "component1;component2",
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component1(I),
+ // handle kind 0x1 : GETFIELD
+ jdk14/AllStructures$RecordSubType.component2(Ljava/util/List;)
+ ]
+ IRETURN
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public component1()I
+ @Lannotations/VTUA;(v=2)
+ @Lannotations/ITUA;(v=3) // invisible
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ GETFIELD jdk14/AllStructures$RecordSubType.component1 : I
+ IRETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ // signature ()Ljava/util/List<Ljava/lang/String;>;
+ // declaration: java.util.List<java.lang.String> component2()
+ public component2()Ljava/util/List;
+ @Lannotations/VTUA;(v=6)
+ @Lannotations/ITUA;(v=7) // invisible
+ L0
+ LINENUMBER 38 L0
+ ALOAD 0
+ GETFIELD jdk14/AllStructures$RecordSubType.component2 : Ljava/util/List;
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk15.AllStructures.txt b/asm-util/src/test/resources/jdk15.AllStructures.txt
new file mode 100644
index 00000000..66343e01
--- /dev/null
+++ b/asm-util/src/test/resources/jdk15.AllStructures.txt
@@ -0,0 +1,14 @@
+// class version 59.65535 (-65477)
+// access flags 0x601
+public abstract interface jdk15/AllStructures {
+
+ // compiled from: AllStructures.java
+ NESTMEMBER jdk15/AllStructures$RecordSubType
+ NESTMEMBER jdk15/AllStructures$ClassSubType
+ PERMITTEDSUBCLASS jdk15/AllStructures$ClassSubType
+ PERMITTEDSUBCLASS jdk15/AllStructures$RecordSubType
+ // access flags 0x19
+ public final static INNERCLASS jdk15/AllStructures$RecordSubType jdk15/AllStructures RecordSubType
+ // access flags 0x19
+ public final static INNERCLASS jdk15/AllStructures$ClassSubType jdk15/AllStructures ClassSubType
+}
diff --git a/asm-util/src/test/resources/jdk3.AllInstructions.txt b/asm-util/src/test/resources/jdk3.AllInstructions.txt
new file mode 100644
index 00000000..6abf2a12
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.AllInstructions.txt
@@ -0,0 +1,1714 @@
+// class version 45.3 (196653)
+// access flags 0x20
+class jdk3/AllInstructions {
+
+ // compiled from: AllInstructions.java
+
+ // access flags 0x2
+ private I f
+
+ // access flags 0x2
+ private J g
+
+ // access flags 0x2
+ private Ljdk3/AllInstructions; field
+
+ // access flags 0xA
+ private static Ljdk3/AllInstructions; staticField
+
+ // access flags 0x0
+ <init>()V
+ L0
+ LINENUMBER 41 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x0
+ <init>(IFJDLjava/lang/Object;)V
+ L0
+ LINENUMBER 43 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L1 0
+ LOCALVARIABLE v0 I L0 L1 1
+ LOCALVARIABLE v1 F L0 L1 2
+ LOCALVARIABLE v2 J L0 L1 3
+ LOCALVARIABLE v3 D L0 L1 5
+ LOCALVARIABLE v4 Ljava/lang/Object; L0 L1 7
+ MAXSTACK = 1
+ MAXLOCALS = 8
+
+ // access flags 0x9
+ public static intInstructions(IIIIIIIII)I
+ L0
+ LINENUMBER 47 L0
+ ILOAD 0
+ ICONST_M1
+ IF_ICMPGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 9
+ L3
+ LINENUMBER 48 L3
+ ILOAD 1
+ ICONST_1
+ IF_ICMPLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 10
+ L6
+ LINENUMBER 49 L6
+ ILOAD 2
+ ICONST_2
+ IF_ICMPGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 11
+ L9
+ LINENUMBER 50 L9
+ ILOAD 3
+ ICONST_3
+ IF_ICMPLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 12
+ L12
+ LINENUMBER 51 L12
+ ILOAD 4
+ ICONST_4
+ IF_ICMPNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 13
+ L15
+ LINENUMBER 52 L15
+ ILOAD 5
+ ICONST_5
+ IF_ICMPEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 14
+ L18
+ LINENUMBER 53 L18
+ ILOAD 9
+ IFEQ L19
+ ILOAD 6
+ ICONST_5
+ IADD
+ GOTO L20
+ L19
+ ILOAD 6
+ ICONST_5
+ ISUB
+ L20
+ ISTORE 0
+ L21
+ LINENUMBER 54 L21
+ ILOAD 10
+ IFEQ L22
+ ILOAD 7
+ BIPUSH 100
+ IMUL
+ GOTO L23
+ L22
+ ILOAD 7
+ BIPUSH 100
+ IDIV
+ L23
+ ISTORE 1
+ L24
+ LINENUMBER 55 L24
+ ILOAD 11
+ IFEQ L25
+ ILOAD 8
+ SIPUSH 10000
+ IREM
+ GOTO L26
+ L25
+ ILOAD 8
+ ICONST_M1
+ IXOR
+ L26
+ ISTORE 2
+ L27
+ LINENUMBER 56 L27
+ ILOAD 12
+ IFEQ L28
+ ILOAD 0
+ LDC 1000000
+ IAND
+ GOTO L29
+ L28
+ ILOAD 0
+ LDC 1000000
+ IOR
+ L29
+ ISTORE 3
+ L30
+ LINENUMBER 57 L30
+ ILOAD 13
+ IFEQ L31
+ ILOAD 1
+ ILOAD 2
+ IXOR
+ GOTO L32
+ L31
+ ILOAD 1
+ ILOAD 2
+ ISHL
+ L32
+ ISTORE 4
+ L33
+ LINENUMBER 58 L33
+ ILOAD 14
+ IFEQ L34
+ ILOAD 2
+ ILOAD 3
+ ISHR
+ GOTO L35
+ L34
+ ILOAD 2
+ ILOAD 3
+ IUSHR
+ L35
+ ISTORE 5
+ L36
+ LINENUMBER 59 L36
+ IINC 6 1
+ L37
+ LINENUMBER 60 L37
+ ILOAD 6
+ IFGE L38
+ ILOAD 6
+ INEG
+ GOTO L39
+ L38
+ ILOAD 6
+ L39
+ ISTORE 7
+ L40
+ LINENUMBER 61 L40
+ ILOAD 0
+ IFGE L41
+ ILOAD 1
+ GOTO L42
+ L41
+ ILOAD 2
+ L42
+ ISTORE 1
+ L43
+ LINENUMBER 62 L43
+ ILOAD 1
+ IFLE L44
+ ILOAD 2
+ GOTO L45
+ L44
+ ILOAD 3
+ L45
+ ISTORE 2
+ L46
+ LINENUMBER 63 L46
+ ILOAD 2
+ IFGT L47
+ ILOAD 3
+ GOTO L48
+ L47
+ ILOAD 4
+ L48
+ ISTORE 3
+ L49
+ LINENUMBER 64 L49
+ ILOAD 3
+ IFLT L50
+ ILOAD 4
+ GOTO L51
+ L50
+ ILOAD 5
+ L51
+ ISTORE 4
+ L52
+ LINENUMBER 65 L52
+ ILOAD 4
+ IFNE L53
+ ILOAD 5
+ GOTO L54
+ L53
+ ILOAD 6
+ L54
+ ISTORE 5
+ L55
+ LINENUMBER 66 L55
+ ILOAD 5
+ IFEQ L56
+ ILOAD 6
+ GOTO L57
+ L56
+ ILOAD 7
+ L57
+ ISTORE 6
+ L58
+ LINENUMBER 67 L58
+ ILOAD 0
+ ILOAD 1
+ IADD
+ ILOAD 2
+ IADD
+ ILOAD 3
+ IADD
+ ILOAD 4
+ IADD
+ ILOAD 5
+ IADD
+ ILOAD 6
+ IADD
+ ILOAD 7
+ IADD
+ ILOAD 8
+ IADD
+ IRETURN
+ L59
+ LOCALVARIABLE v0 I L0 L59 0
+ LOCALVARIABLE v1 I L0 L59 1
+ LOCALVARIABLE v2 I L0 L59 2
+ LOCALVARIABLE v3 I L0 L59 3
+ LOCALVARIABLE v4 I L0 L59 4
+ LOCALVARIABLE v5 I L0 L59 5
+ LOCALVARIABLE v6 I L0 L59 6
+ LOCALVARIABLE v7 I L0 L59 7
+ LOCALVARIABLE v8 I L0 L59 8
+ LOCALVARIABLE b0 Z L3 L59 9
+ LOCALVARIABLE b1 Z L6 L59 10
+ LOCALVARIABLE b2 Z L9 L59 11
+ LOCALVARIABLE b3 Z L12 L59 12
+ LOCALVARIABLE b4 Z L15 L59 13
+ LOCALVARIABLE b5 Z L18 L59 14
+ MAXSTACK = 2
+ MAXLOCALS = 15
+
+ // access flags 0x9
+ public static longInstructions(JJJJJJJJJ)J
+ L0
+ LINENUMBER 72 L0
+ LLOAD 0
+ LDC -1
+ LCMP
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 18
+ L3
+ LINENUMBER 73 L3
+ LLOAD 2
+ LCONST_1
+ LCMP
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 19
+ L6
+ LINENUMBER 74 L6
+ LLOAD 4
+ LDC 2
+ LCMP
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 20
+ L9
+ LINENUMBER 75 L9
+ LLOAD 6
+ LDC 3
+ LCMP
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 21
+ L12
+ LINENUMBER 76 L12
+ LLOAD 8
+ LDC 4
+ LCMP
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 22
+ L15
+ LINENUMBER 77 L15
+ LLOAD 10
+ LDC 5
+ LCMP
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 23
+ L18
+ LINENUMBER 78 L18
+ ILOAD 18
+ IFEQ L19
+ LLOAD 12
+ LDC 5
+ LADD
+ GOTO L20
+ L19
+ LLOAD 12
+ LDC 5
+ LSUB
+ L20
+ LSTORE 0
+ L21
+ LINENUMBER 79 L21
+ ILOAD 19
+ IFEQ L22
+ LLOAD 14
+ LDC 100
+ LMUL
+ GOTO L23
+ L22
+ LLOAD 14
+ LDC 100
+ LDIV
+ L23
+ LSTORE 2
+ L24
+ LINENUMBER 80 L24
+ ILOAD 20
+ IFEQ L25
+ LLOAD 16
+ LDC 10000
+ LREM
+ GOTO L26
+ L25
+ LLOAD 16
+ LDC -1
+ LXOR
+ L26
+ LSTORE 4
+ L27
+ LINENUMBER 81 L27
+ ILOAD 21
+ IFEQ L28
+ LLOAD 0
+ LDC 1000000
+ LAND
+ GOTO L29
+ L28
+ LLOAD 0
+ LDC 1000000
+ LOR
+ L29
+ LSTORE 6
+ L30
+ LINENUMBER 82 L30
+ ILOAD 22
+ IFEQ L31
+ LLOAD 2
+ LLOAD 4
+ LXOR
+ GOTO L32
+ L31
+ LLOAD 2
+ LLOAD 4
+ L2I
+ LSHL
+ L32
+ LSTORE 8
+ L33
+ LINENUMBER 83 L33
+ ILOAD 23
+ IFEQ L34
+ LLOAD 4
+ LLOAD 6
+ L2I
+ LSHR
+ GOTO L35
+ L34
+ LLOAD 4
+ LLOAD 6
+ L2I
+ LUSHR
+ L35
+ LSTORE 10
+ L36
+ LINENUMBER 84 L36
+ LLOAD 12
+ LCONST_1
+ LADD
+ LSTORE 12
+ L37
+ LINENUMBER 85 L37
+ LLOAD 12
+ LCONST_0
+ LCMP
+ IFGE L38
+ LLOAD 12
+ LNEG
+ GOTO L39
+ L38
+ LLOAD 12
+ L39
+ LSTORE 14
+ L40
+ LINENUMBER 86 L40
+ LLOAD 0
+ LLOAD 2
+ LADD
+ LLOAD 4
+ LADD
+ LLOAD 6
+ LADD
+ LLOAD 8
+ LADD
+ LLOAD 10
+ LADD
+ LLOAD 12
+ LADD
+ LLOAD 14
+ LADD
+ LLOAD 16
+ LADD
+ LRETURN
+ L41
+ LOCALVARIABLE v0 J L0 L41 0
+ LOCALVARIABLE v1 J L0 L41 2
+ LOCALVARIABLE v2 J L0 L41 4
+ LOCALVARIABLE v3 J L0 L41 6
+ LOCALVARIABLE v4 J L0 L41 8
+ LOCALVARIABLE v5 J L0 L41 10
+ LOCALVARIABLE v6 J L0 L41 12
+ LOCALVARIABLE v7 J L0 L41 14
+ LOCALVARIABLE v8 J L0 L41 16
+ LOCALVARIABLE b0 Z L3 L41 18
+ LOCALVARIABLE b1 Z L6 L41 19
+ LOCALVARIABLE b2 Z L9 L41 20
+ LOCALVARIABLE b3 Z L12 L41 21
+ LOCALVARIABLE b4 Z L15 L41 22
+ LOCALVARIABLE b5 Z L18 L41 23
+ MAXSTACK = 4
+ MAXLOCALS = 24
+
+ // access flags 0x9
+ public static floatInstructions(FFFFFFFFF)F
+ L0
+ LINENUMBER 91 L0
+ FLOAD 0
+ LDC -1.0
+ FCMPG
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 9
+ L3
+ LINENUMBER 92 L3
+ FLOAD 1
+ FCONST_1
+ FCMPL
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 10
+ L6
+ LINENUMBER 93 L6
+ FLOAD 2
+ FCONST_2
+ FCMPG
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 11
+ L9
+ LINENUMBER 94 L9
+ FLOAD 3
+ LDC 3.0
+ FCMPL
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 12
+ L12
+ LINENUMBER 95 L12
+ FLOAD 4
+ LDC 4.0
+ FCMPL
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 13
+ L15
+ LINENUMBER 96 L15
+ FLOAD 5
+ LDC 5.0
+ FCMPL
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 14
+ L18
+ LINENUMBER 97 L18
+ ILOAD 9
+ IFEQ L19
+ FLOAD 6
+ LDC 5.0
+ FADD
+ GOTO L20
+ L19
+ FLOAD 6
+ LDC 5.0
+ FSUB
+ L20
+ FSTORE 0
+ L21
+ LINENUMBER 98 L21
+ ILOAD 10
+ IFEQ L22
+ FLOAD 7
+ LDC 100.0
+ FMUL
+ GOTO L23
+ L22
+ FLOAD 7
+ LDC 100.0
+ FDIV
+ L23
+ FSTORE 1
+ L24
+ LINENUMBER 99 L24
+ ILOAD 11
+ IFEQ L25
+ FLOAD 8
+ LDC 10000.0
+ FREM
+ GOTO L26
+ L25
+ FLOAD 8
+ L26
+ FSTORE 2
+ L27
+ LINENUMBER 100 L27
+ ILOAD 12
+ IFEQ L28
+ FLOAD 3
+ FNEG
+ GOTO L29
+ L28
+ FLOAD 3
+ L29
+ FSTORE 3
+ L30
+ LINENUMBER 101 L30
+ ILOAD 13
+ IFEQ L31
+ FLOAD 4
+ FNEG
+ GOTO L32
+ L31
+ FLOAD 4
+ L32
+ FSTORE 4
+ L33
+ LINENUMBER 102 L33
+ ILOAD 14
+ IFEQ L34
+ FLOAD 5
+ FNEG
+ GOTO L35
+ L34
+ FLOAD 5
+ L35
+ FSTORE 5
+ L36
+ LINENUMBER 103 L36
+ FLOAD 6
+ FCONST_1
+ FADD
+ FSTORE 6
+ L37
+ LINENUMBER 104 L37
+ FLOAD 6
+ FCONST_0
+ FCMPG
+ IFGE L38
+ FLOAD 6
+ FNEG
+ GOTO L39
+ L38
+ FLOAD 6
+ L39
+ FSTORE 7
+ L40
+ LINENUMBER 105 L40
+ FLOAD 7
+ FSTORE 8
+ L41
+ LINENUMBER 106 L41
+ FLOAD 0
+ FLOAD 1
+ FADD
+ FLOAD 2
+ FADD
+ FLOAD 3
+ FADD
+ FLOAD 4
+ FADD
+ FLOAD 5
+ FADD
+ FLOAD 6
+ FADD
+ FLOAD 7
+ FADD
+ FLOAD 8
+ FADD
+ FRETURN
+ L42
+ LOCALVARIABLE v0 F L0 L42 0
+ LOCALVARIABLE v1 F L0 L42 1
+ LOCALVARIABLE v2 F L0 L42 2
+ LOCALVARIABLE v3 F L0 L42 3
+ LOCALVARIABLE v4 F L0 L42 4
+ LOCALVARIABLE v5 F L0 L42 5
+ LOCALVARIABLE v6 F L0 L42 6
+ LOCALVARIABLE v7 F L0 L42 7
+ LOCALVARIABLE v8 F L0 L42 8
+ LOCALVARIABLE b0 Z L3 L42 9
+ LOCALVARIABLE b1 Z L6 L42 10
+ LOCALVARIABLE b2 Z L9 L42 11
+ LOCALVARIABLE b3 Z L12 L42 12
+ LOCALVARIABLE b4 Z L15 L42 13
+ LOCALVARIABLE b5 Z L18 L42 14
+ MAXSTACK = 2
+ MAXLOCALS = 15
+
+ // access flags 0x9
+ public static doubleInstructions(DDDDDDDDD)D
+ L0
+ LINENUMBER 119 L0
+ DLOAD 0
+ LDC -1.0
+ DCMPG
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 18
+ L3
+ LINENUMBER 120 L3
+ DLOAD 2
+ DCONST_1
+ DCMPL
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 19
+ L6
+ LINENUMBER 121 L6
+ DLOAD 4
+ LDC 2.0
+ DCMPG
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 20
+ L9
+ LINENUMBER 122 L9
+ DLOAD 6
+ LDC 3.0
+ DCMPL
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 21
+ L12
+ LINENUMBER 123 L12
+ DLOAD 8
+ LDC 4.0
+ DCMPL
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 22
+ L15
+ LINENUMBER 124 L15
+ DLOAD 10
+ LDC 5.0
+ DCMPL
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 23
+ L18
+ LINENUMBER 125 L18
+ ILOAD 18
+ IFEQ L19
+ DLOAD 12
+ LDC 5.0
+ DADD
+ GOTO L20
+ L19
+ DLOAD 12
+ LDC 5.0
+ DSUB
+ L20
+ DSTORE 0
+ L21
+ LINENUMBER 126 L21
+ ILOAD 19
+ IFEQ L22
+ DLOAD 14
+ LDC 100.0
+ DMUL
+ GOTO L23
+ L22
+ DLOAD 14
+ LDC 100.0
+ DDIV
+ L23
+ DSTORE 2
+ L24
+ LINENUMBER 127 L24
+ ILOAD 20
+ IFEQ L25
+ DLOAD 16
+ LDC 10000.0
+ DREM
+ GOTO L26
+ L25
+ DLOAD 16
+ L26
+ DSTORE 4
+ L27
+ LINENUMBER 128 L27
+ ILOAD 21
+ IFEQ L28
+ DLOAD 6
+ DNEG
+ GOTO L29
+ L28
+ DLOAD 6
+ L29
+ DSTORE 6
+ L30
+ LINENUMBER 129 L30
+ ILOAD 22
+ IFEQ L31
+ DLOAD 8
+ DNEG
+ GOTO L32
+ L31
+ DLOAD 8
+ L32
+ DSTORE 8
+ L33
+ LINENUMBER 130 L33
+ ILOAD 23
+ IFEQ L34
+ DLOAD 10
+ DNEG
+ GOTO L35
+ L34
+ DLOAD 10
+ L35
+ DSTORE 10
+ L36
+ LINENUMBER 131 L36
+ DLOAD 12
+ DCONST_1
+ DADD
+ DSTORE 12
+ L37
+ LINENUMBER 132 L37
+ DLOAD 12
+ DCONST_0
+ DCMPG
+ IFGE L38
+ DLOAD 12
+ DNEG
+ GOTO L39
+ L38
+ DLOAD 12
+ L39
+ DSTORE 14
+ L40
+ LINENUMBER 133 L40
+ DLOAD 0
+ DLOAD 2
+ DADD
+ DLOAD 4
+ DADD
+ DLOAD 6
+ DADD
+ DLOAD 8
+ DADD
+ DLOAD 10
+ DADD
+ DLOAD 12
+ DADD
+ DLOAD 14
+ DADD
+ DLOAD 16
+ DADD
+ DRETURN
+ L41
+ LOCALVARIABLE v0 D L0 L41 0
+ LOCALVARIABLE v1 D L0 L41 2
+ LOCALVARIABLE v2 D L0 L41 4
+ LOCALVARIABLE v3 D L0 L41 6
+ LOCALVARIABLE v4 D L0 L41 8
+ LOCALVARIABLE v5 D L0 L41 10
+ LOCALVARIABLE v6 D L0 L41 12
+ LOCALVARIABLE v7 D L0 L41 14
+ LOCALVARIABLE v8 D L0 L41 16
+ LOCALVARIABLE b0 Z L3 L41 18
+ LOCALVARIABLE b1 Z L6 L41 19
+ LOCALVARIABLE b2 Z L9 L41 20
+ LOCALVARIABLE b3 Z L12 L41 21
+ LOCALVARIABLE b4 Z L15 L41 22
+ LOCALVARIABLE b5 Z L18 L41 23
+ MAXSTACK = 4
+ MAXLOCALS = 24
+
+ // access flags 0x9
+ public static castInstructions(IJJ)D
+ L0
+ LINENUMBER 137 L0
+ ILOAD 0
+ I2B
+ ISTORE 5
+ L1
+ LINENUMBER 138 L1
+ LLOAD 1
+ L2I
+ I2C
+ ISTORE 6
+ L2
+ LINENUMBER 139 L2
+ LLOAD 3
+ L2I
+ I2S
+ ISTORE 7
+ L3
+ LINENUMBER 140 L3
+ ILOAD 5
+ I2L
+ LSTORE 8
+ L4
+ LINENUMBER 141 L4
+ ILOAD 6
+ I2F
+ FSTORE 10
+ L5
+ LINENUMBER 142 L5
+ ILOAD 7
+ I2D
+ DSTORE 11
+ L6
+ LINENUMBER 143 L6
+ LLOAD 8
+ LSTORE 1
+ L7
+ LINENUMBER 144 L7
+ LLOAD 1
+ LSTORE 3
+ L8
+ LINENUMBER 145 L8
+ DLOAD 11
+ D2L
+ LSTORE 8
+ L9
+ LINENUMBER 146 L9
+ ILOAD 0
+ I2L
+ LLOAD 1
+ LADD
+ LLOAD 3
+ LADD
+ ILOAD 5
+ I2L
+ LADD
+ ILOAD 6
+ I2L
+ LADD
+ ILOAD 7
+ I2L
+ LADD
+ LLOAD 8
+ LADD
+ L2F
+ FLOAD 10
+ FADD
+ F2D
+ DLOAD 11
+ DADD
+ DRETURN
+ L10
+ LOCALVARIABLE v0 I L0 L10 0
+ LOCALVARIABLE v1 J L0 L10 1
+ LOCALVARIABLE v2 J L0 L10 3
+ LOCALVARIABLE v3 B L1 L10 5
+ LOCALVARIABLE v4 C L2 L10 6
+ LOCALVARIABLE v5 S L3 L10 7
+ LOCALVARIABLE v6 J L4 L10 8
+ LOCALVARIABLE v7 F L5 L10 10
+ LOCALVARIABLE v8 D L6 L10 11
+ MAXSTACK = 4
+ MAXLOCALS = 13
+
+ // access flags 0x9
+ public static castInstructions(FDD)F
+ L0
+ LINENUMBER 150 L0
+ FLOAD 0
+ F2I
+ I2B
+ ISTORE 5
+ L1
+ LINENUMBER 151 L1
+ DLOAD 1
+ D2I
+ I2C
+ ISTORE 6
+ L2
+ LINENUMBER 152 L2
+ DLOAD 3
+ D2I
+ I2S
+ ISTORE 7
+ L3
+ LINENUMBER 153 L3
+ ILOAD 5
+ I2L
+ LSTORE 8
+ L4
+ LINENUMBER 154 L4
+ ILOAD 6
+ I2F
+ FSTORE 10
+ L5
+ LINENUMBER 155 L5
+ ILOAD 7
+ I2D
+ DSTORE 11
+ L6
+ LINENUMBER 156 L6
+ LLOAD 8
+ L2D
+ DSTORE 1
+ L7
+ LINENUMBER 157 L7
+ DLOAD 1
+ DSTORE 3
+ L8
+ LINENUMBER 158 L8
+ FLOAD 10
+ F2L
+ LSTORE 8
+ L9
+ LINENUMBER 159 L9
+ FLOAD 0
+ F2D
+ DLOAD 1
+ DADD
+ DLOAD 3
+ DADD
+ ILOAD 5
+ I2D
+ DADD
+ ILOAD 6
+ I2D
+ DADD
+ ILOAD 7
+ I2D
+ DADD
+ LLOAD 8
+ L2D
+ DADD
+ FLOAD 10
+ F2D
+ DADD
+ DLOAD 11
+ DADD
+ D2F
+ FRETURN
+ L10
+ LOCALVARIABLE v0 F L0 L10 0
+ LOCALVARIABLE v1 D L0 L10 1
+ LOCALVARIABLE v2 D L0 L10 3
+ LOCALVARIABLE v3 B L1 L10 5
+ LOCALVARIABLE v4 C L2 L10 6
+ LOCALVARIABLE v5 S L3 L10 7
+ LOCALVARIABLE v6 J L4 L10 8
+ LOCALVARIABLE v7 F L5 L10 10
+ LOCALVARIABLE v8 D L6 L10 11
+ MAXSTACK = 4
+ MAXLOCALS = 13
+
+ // access flags 0x9
+ public static objectInstructions(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+ L0
+ LINENUMBER 163 L0
+ ALOAD 0
+ ALOAD 1
+ IF_ACMPNE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 5
+ L3
+ LINENUMBER 164 L3
+ ALOAD 1
+ ALOAD 2
+ IF_ACMPEQ L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 6
+ L6
+ LINENUMBER 165 L6
+ ALOAD 2
+ IFNONNULL L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 7
+ L9
+ LINENUMBER 166 L9
+ ALOAD 3
+ IFNULL L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 8
+ L12
+ LINENUMBER 167 L12
+ ALOAD 4
+ INSTANCEOF java/lang/String
+ ISTORE 9
+ L13
+ LINENUMBER 168 L13
+ ILOAD 5
+ IFEQ L14
+ ACONST_NULL
+ GOTO L15
+ L14
+ ALOAD 0
+ L15
+ ASTORE 0
+ L16
+ LINENUMBER 169 L16
+ ILOAD 6
+ IFEQ L17
+ ALOAD 1
+ GOTO L18
+ L17
+ ALOAD 0
+ L18
+ ASTORE 1
+ L19
+ LINENUMBER 170 L19
+ ILOAD 7
+ IFEQ L20
+ ALOAD 2
+ GOTO L21
+ L20
+ ALOAD 1
+ L21
+ ASTORE 2
+ L22
+ LINENUMBER 171 L22
+ ILOAD 8
+ IFEQ L23
+ ALOAD 3
+ GOTO L24
+ L23
+ ALOAD 2
+ L24
+ ASTORE 3
+ L25
+ LINENUMBER 172 L25
+ ILOAD 9
+ IFEQ L26
+ NEW java/lang/Integer
+ DUP
+ ALOAD 4
+ CHECKCAST java/lang/String
+ INVOKEVIRTUAL java/lang/String.length ()I
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ GOTO L27
+ L26
+ ALOAD 3
+ L27
+ ASTORE 4
+ L28
+ LINENUMBER 173 L28
+ ALOAD 4
+ ARETURN
+ L29
+ LOCALVARIABLE v0 Ljava/lang/Object; L0 L29 0
+ LOCALVARIABLE v1 Ljava/lang/Object; L0 L29 1
+ LOCALVARIABLE v2 Ljava/lang/Object; L0 L29 2
+ LOCALVARIABLE v3 Ljava/lang/Object; L0 L29 3
+ LOCALVARIABLE v4 Ljava/lang/Object; L0 L29 4
+ LOCALVARIABLE b0 Z L3 L29 5
+ LOCALVARIABLE b1 Z L6 L29 6
+ LOCALVARIABLE b2 Z L9 L29 7
+ LOCALVARIABLE b3 Z L12 L29 8
+ LOCALVARIABLE b4 Z L13 L29 9
+ MAXSTACK = 3
+ MAXLOCALS = 10
+
+ // access flags 0x9
+ public static arrayInstructions([B[C[S[I[J[F[D[Ljava/lang/Object;)[Ljava/lang/Object;
+ L0
+ LINENUMBER 178 L0
+ ALOAD 0
+ ICONST_1
+ ALOAD 0
+ ICONST_0
+ BALOAD
+ BASTORE
+ L1
+ LINENUMBER 179 L1
+ ALOAD 1
+ ICONST_1
+ ALOAD 1
+ ICONST_0
+ CALOAD
+ CASTORE
+ L2
+ LINENUMBER 180 L2
+ ALOAD 2
+ ICONST_1
+ ALOAD 2
+ ICONST_0
+ SALOAD
+ SASTORE
+ L3
+ LINENUMBER 181 L3
+ ALOAD 3
+ ICONST_1
+ ALOAD 3
+ ICONST_0
+ IALOAD
+ IASTORE
+ L4
+ LINENUMBER 182 L4
+ ALOAD 4
+ ICONST_1
+ ALOAD 4
+ ICONST_0
+ LALOAD
+ LASTORE
+ L5
+ LINENUMBER 183 L5
+ ALOAD 5
+ ICONST_1
+ ALOAD 5
+ ICONST_0
+ FALOAD
+ FASTORE
+ L6
+ LINENUMBER 184 L6
+ ALOAD 6
+ ICONST_1
+ ALOAD 6
+ ICONST_0
+ DALOAD
+ DASTORE
+ L7
+ LINENUMBER 185 L7
+ ALOAD 7
+ ICONST_1
+ ALOAD 7
+ ICONST_0
+ AALOAD
+ AASTORE
+ L8
+ LINENUMBER 186 L8
+ ALOAD 7
+ ARRAYLENGTH
+ ANEWARRAY java/lang/Object
+ ASTORE 8
+ L9
+ LINENUMBER 187 L9
+ ALOAD 8
+ ICONST_0
+ ICONST_4
+ BIPUSH 8
+ BIPUSH 16
+ MULTIANEWARRAY [[[I 3
+ AASTORE
+ L10
+ LINENUMBER 188 L10
+ ALOAD 8
+ ARETURN
+ L11
+ LOCALVARIABLE v0 [B L0 L11 0
+ LOCALVARIABLE v1 [C L0 L11 1
+ LOCALVARIABLE v2 [S L0 L11 2
+ LOCALVARIABLE v3 [I L0 L11 3
+ LOCALVARIABLE v4 [J L0 L11 4
+ LOCALVARIABLE v5 [F L0 L11 5
+ LOCALVARIABLE v6 [D L0 L11 6
+ LOCALVARIABLE v7 [Ljava/lang/Object; L0 L11 7
+ LOCALVARIABLE v8 [Ljava/lang/Object; L9 L11 8
+ MAXSTACK = 5
+ MAXLOCALS = 9
+
+ // access flags 0x1
+ public fieldInstructions()V
+ L0
+ LINENUMBER 192 L0
+ ALOAD 0
+ GETFIELD jdk3/AllInstructions.field : Ljdk3/AllInstructions;
+ ASTORE 1
+ L1
+ LINENUMBER 193 L1
+ ALOAD 0
+ GETSTATIC jdk3/AllInstructions.staticField : Ljdk3/AllInstructions;
+ PUTFIELD jdk3/AllInstructions.field : Ljdk3/AllInstructions;
+ L2
+ LINENUMBER 194 L2
+ ALOAD 1
+ PUTSTATIC jdk3/AllInstructions.staticField : Ljdk3/AllInstructions;
+ L3
+ LINENUMBER 195 L3
+ RETURN
+ L4
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L4 0
+ LOCALVARIABLE c Ljdk3/AllInstructions; L1 L3 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public methodInstructions(Ljava/lang/Runnable;)V
+ L0
+ LINENUMBER 198 L0
+ NEW jdk3/AllInstructions
+ DUP
+ INVOKESPECIAL jdk3/AllInstructions.<init> ()V
+ ASTORE 2
+ L1
+ LINENUMBER 199 L1
+ ALOAD 2
+ INVOKEVIRTUAL jdk3/AllInstructions.fieldInstructions ()V
+ L2
+ LINENUMBER 200 L2
+ ALOAD 2
+ INVOKESTATIC jdk3/AllInstructions.monitorInstructions (Ljava/lang/Object;)Ljava/lang/String;
+ POP
+ L3
+ LINENUMBER 201 L3
+ ALOAD 1
+ INVOKEINTERFACE java/lang/Runnable.run ()V (itf)
+ L4
+ LINENUMBER 202 L4
+ RETURN
+ L5
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L5 0
+ LOCALVARIABLE v0 Ljava/lang/Runnable; L0 L5 1
+ LOCALVARIABLE c Ljdk3/AllInstructions; L1 L4 2
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x9
+ public static lookupSwitchInstruction(I)I
+ L0
+ LINENUMBER 205 L0
+ ILOAD 0
+ LOOKUPSWITCH
+ 1000: L1
+ 10000: L2
+ 100000: L3
+ default: L4
+ L1
+ LINENUMBER 207 L1
+ ICONST_1
+ IRETURN
+ L2
+ LINENUMBER 209 L2
+ ICONST_2
+ IRETURN
+ L3
+ LINENUMBER 211 L3
+ ICONST_3
+ IRETURN
+ L4
+ LINENUMBER 213 L4
+ ICONST_M1
+ IRETURN
+ L5
+ LOCALVARIABLE v0 I L0 L5 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static tableSwitchInstruction(I)I
+ L0
+ LINENUMBER 218 L0
+ ILOAD 0
+ TABLESWITCH
+ 0: L1
+ 1: L2
+ 2: L3
+ default: L4
+ L1
+ LINENUMBER 220 L1
+ ICONST_1
+ IRETURN
+ L2
+ LINENUMBER 222 L2
+ ICONST_2
+ IRETURN
+ L3
+ LINENUMBER 224 L3
+ ICONST_3
+ IRETURN
+ L4
+ LINENUMBER 226 L4
+ ICONST_M1
+ IRETURN
+ L5
+ LOCALVARIABLE v0 I L0 L5 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static monitorInstructions(Ljava/lang/Object;)Ljava/lang/String;
+ TRYCATCHBLOCK L0 L1 L1 null
+ L2
+ LINENUMBER 231 L2
+ ALOAD 0
+ ASTORE 1
+ ALOAD 1
+ MONITORENTER
+ L0
+ LINENUMBER 232 L0
+ ALOAD 0
+ INVOKEVIRTUAL java/lang/Object.toString ()Ljava/lang/String;
+ ASTORE 2
+ ALOAD 1
+ MONITOREXIT
+ ALOAD 2
+ ARETURN
+ L1
+ LINENUMBER 233 L1
+ ASTORE 3
+ ALOAD 1
+ MONITOREXIT
+ ALOAD 3
+ ATHROW
+ L3
+ LOCALVARIABLE v0 Ljava/lang/Object; L2 L3 0
+ MAXSTACK = 1
+ MAXLOCALS = 4
+
+ // access flags 0x1
+ public dupX1Instruction()I
+ L0
+ LINENUMBER 237 L0
+ ALOAD 0
+ DUP
+ GETFIELD jdk3/AllInstructions.f : I
+ DUP_X1
+ ICONST_1
+ IADD
+ PUTFIELD jdk3/AllInstructions.f : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L1 0
+ MAXSTACK = 4
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public dup2Instruction([JII)V
+ L0
+ LINENUMBER 241 L0
+ ALOAD 1
+ ILOAD 2
+ DUP2
+ LALOAD
+ LCONST_1
+ ILOAD 3
+ LSHL
+ LOR
+ LASTORE
+ L1
+ LINENUMBER 242 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [J L0 L2 1
+ LOCALVARIABLE i I L0 L2 2
+ LOCALVARIABLE j I L0 L2 3
+ MAXSTACK = 7
+ MAXLOCALS = 4
+
+ // access flags 0x1
+ public dup2X1Instruction()J
+ L0
+ LINENUMBER 245 L0
+ ALOAD 0
+ DUP
+ GETFIELD jdk3/AllInstructions.g : J
+ DUP2_X1
+ LCONST_1
+ LADD
+ PUTFIELD jdk3/AllInstructions.g : J
+ LRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L1 0
+ MAXSTACK = 7
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public dup2X1InstructionVariant([Ljava/lang/String;ILjava/lang/Object;)V
+ L0
+ LINENUMBER 249 L0
+ NEW java/lang/StringBuffer
+ DUP
+ INVOKESPECIAL java/lang/StringBuffer.<init> ()V
+ ALOAD 1
+ ILOAD 2
+ DUP2_X1
+ AALOAD
+ INVOKEVIRTUAL java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;
+ LDC " "
+ INVOKEVIRTUAL java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;
+ ALOAD 3
+ INVOKEVIRTUAL java/lang/Object.toString ()Ljava/lang/String;
+ INVOKEVIRTUAL java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;
+ INVOKEVIRTUAL java/lang/StringBuffer.toString ()Ljava/lang/String;
+ AASTORE
+ L1
+ LINENUMBER 250 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [Ljava/lang/String; L0 L2 1
+ LOCALVARIABLE i I L0 L2 2
+ LOCALVARIABLE o Ljava/lang/Object; L0 L2 3
+ MAXSTACK = 5
+ MAXLOCALS = 4
+
+ // access flags 0x1
+ public dupX2Instruction([I[I)V
+ L0
+ LINENUMBER 253 L0
+ ALOAD 1
+ ICONST_0
+ ALOAD 2
+ ICONST_0
+ ICONST_0
+ DUP_X2
+ IASTORE
+ IASTORE
+ L1
+ LINENUMBER 254 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [I L0 L2 1
+ LOCALVARIABLE v1 [I L0 L2 2
+ MAXSTACK = 6
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public dup2X2Instruction([J[J)V
+ L0
+ LINENUMBER 257 L0
+ ALOAD 1
+ ICONST_0
+ ALOAD 2
+ ICONST_0
+ LCONST_0
+ DUP2_X2
+ LASTORE
+ LASTORE
+ L1
+ LINENUMBER 258 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [J L0 L2 1
+ LOCALVARIABLE v1 [J L0 L2 2
+ MAXSTACK = 8
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public popInstructions()V
+ L0
+ LINENUMBER 261 L0
+ ALOAD 0
+ INVOKEVIRTUAL jdk3/AllInstructions.dupX1Instruction ()I
+ POP
+ L1
+ LINENUMBER 262 L1
+ ALOAD 0
+ INVOKEVIRTUAL jdk3/AllInstructions.dup2X1Instruction ()J
+ POP2
+ L2
+ LINENUMBER 263 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk3/AllInstructions; L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public jsrAndRetInstructions(I)I throws java/lang/Exception
+ TRYCATCHBLOCK L0 L1 L2 java/lang/Throwable
+ TRYCATCHBLOCK L0 L3 L3 null
+ L4
+ LINENUMBER 266 L4
+ ILOAD 1
+ ICONST_1
+ IADD
+ ISTORE 2
+ L0
+ LINENUMBER 268 L0
+ ALOAD 0
+ ILOAD 2
+ INVOKEVIRTUAL jdk3/AllInstructions.jsrAndRetInstructions (I)I
+ ISTORE 2
+ L1
+ JSR L5
+ GOTO L6
+ L2
+ LINENUMBER 270 L2
+ ASTORE 3
+ ICONST_M1
+ ISTORE 4
+ JSR L5
+ ILOAD 4
+ IRETURN
+ L3
+ LINENUMBER 272 L3
+ ASTORE 5
+ JSR L5
+ ALOAD 5
+ ATHROW
+ L5
+ ASTORE 6
+ IINC 2 1
+ RET 6
+ L6
+ LINENUMBER 274 L6
+ ILOAD 2
+ IRETURN
+ L7
+ LOCALVARIABLE this Ljdk3/AllInstructions; L4 L7 0
+ LOCALVARIABLE v0 I L4 L7 1
+ LOCALVARIABLE u0 I L0 L7 2
+ LOCALVARIABLE t Ljava/lang/Throwable; L2 L6 3
+ MAXSTACK = 2
+ MAXLOCALS = 7
+
+ // access flags 0x1
+ public readNullArray()Ljava/lang/Object;
+ TRYCATCHBLOCK L0 L1 L1 java/lang/NullPointerException
+ L2
+ LINENUMBER 278 L2
+ ACONST_NULL
+ ASTORE 1
+ L0
+ LINENUMBER 280 L0
+ ALOAD 1
+ ICONST_0
+ AALOAD
+ ARETURN
+ L1
+ LINENUMBER 282 L1
+ ASTORE 2
+ ACONST_NULL
+ ARETURN
+ L3
+ LOCALVARIABLE this Ljdk3/AllInstructions; L2 L3 0
+ LOCALVARIABLE array [Ljava/lang/Object; L0 L3 1
+ LOCALVARIABLE e Ljava/lang/NullPointerException; L1 L3 2
+ MAXSTACK = 2
+ MAXLOCALS = 3
+}
diff --git a/asm-util/src/test/resources/jdk3.AllStructures$1.txt b/asm-util/src/test/resources/jdk3.AllStructures$1.txt
new file mode 100644
index 00000000..3ace619c
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.AllStructures$1.txt
@@ -0,0 +1,62 @@
+// class version 45.3 (196653)
+// access flags 0x20
+class jdk3/AllStructures$1 implements java/lang/Runnable {
+
+ // compiled from: AllStructures.java
+ // access flags 0x0
+ INNERCLASS jdk3/AllStructures$1 null null
+ // access flags 0x2
+ private INNERCLASS jdk3/AllStructures$InnerClass jdk3/AllStructures InnerClass
+
+ // access flags 0x1012
+ private final synthetic Ljdk3/AllStructures; this$0
+
+ // access flags 0x0
+ <init>(Ljdk3/AllStructures;)V
+ L0
+ LINENUMBER 41 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk3/AllStructures$1.this$0 : Ljdk3/AllStructures;
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures$1; L0 L1 0
+ LOCALVARIABLE this$0 Ljdk3/AllStructures; L0 L1 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public run()V
+ L0
+ LINENUMBER 42 L0
+ NEW jdk3/AllStructures$InnerClass
+ DUP
+ ALOAD 0
+ GETFIELD jdk3/AllStructures$1.this$0 : Ljdk3/AllStructures;
+ NEW jdk3/AllStructures$InnerClass
+ DUP
+ ALOAD 0
+ GETFIELD jdk3/AllStructures$1.this$0 : Ljdk3/AllStructures;
+ ALOAD 0
+ GETFIELD jdk3/AllStructures$1.this$0 : Ljdk3/AllStructures;
+ INVOKESTATIC jdk3/AllStructures.access$000 (Ljdk3/AllStructures;)D
+ ALOAD 0
+ GETFIELD jdk3/AllStructures$1.this$0 : Ljdk3/AllStructures;
+ INVOKESTATIC jdk3/AllStructures.access$100 (Ljdk3/AllStructures;)D
+ DADD
+ ACONST_NULL
+ INVOKESPECIAL jdk3/AllStructures$InnerClass.<init> (Ljdk3/AllStructures;DLjdk3/AllStructures$1;)V
+ INVOKESTATIC jdk3/AllStructures$InnerClass.access$300 (Ljdk3/AllStructures$InnerClass;)D
+ ACONST_NULL
+ INVOKESPECIAL jdk3/AllStructures$InnerClass.<init> (Ljdk3/AllStructures;DLjdk3/AllStructures$1;)V
+ POP
+ L1
+ LINENUMBER 43 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk3/AllStructures$1; L0 L2 0
+ MAXSTACK = 10
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk3.AllStructures$InnerClass.txt b/asm-util/src/test/resources/jdk3.AllStructures$InnerClass.txt
new file mode 100644
index 00000000..d534ecc5
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.AllStructures$InnerClass.txt
@@ -0,0 +1,69 @@
+// class version 45.3 (196653)
+// access flags 0x20
+class jdk3/AllStructures$InnerClass {
+
+ // compiled from: AllStructures.java
+ // access flags 0x2
+ private INNERCLASS jdk3/AllStructures$InnerClass jdk3/AllStructures InnerClass
+ // access flags 0x0
+ INNERCLASS jdk3/AllStructures$1 null null
+
+ // access flags 0x12
+ private final D f0
+
+ // access flags 0x1012
+ private final synthetic Ljdk3/AllStructures; this$0
+
+ // access flags 0x2
+ private <init>(Ljdk3/AllStructures;D)V
+ L0
+ LINENUMBER 49 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk3/AllStructures$InnerClass.this$0 : Ljdk3/AllStructures;
+ L1
+ LINENUMBER 50 L1
+ ALOAD 0
+ DLOAD 2
+ PUTFIELD jdk3/AllStructures$InnerClass.f0 : D
+ L2
+ LINENUMBER 51 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk3/AllStructures$InnerClass; L0 L3 0
+ LOCALVARIABLE this$0 Ljdk3/AllStructures; L0 L3 1
+ LOCALVARIABLE f0 D L0 L3 2
+ MAXSTACK = 3
+ MAXLOCALS = 4
+
+ // access flags 0x1000
+ synthetic <init>(Ljdk3/AllStructures;DLjdk3/AllStructures$1;)V
+ L0
+ LINENUMBER 47 L0
+ ALOAD 0
+ ALOAD 1
+ DLOAD 2
+ INVOKESPECIAL jdk3/AllStructures$InnerClass.<init> (Ljdk3/AllStructures;D)V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures$InnerClass; L0 L1 0
+ LOCALVARIABLE x0 Ljdk3/AllStructures; L0 L1 1
+ LOCALVARIABLE x1 D L0 L1 2
+ LOCALVARIABLE x2 Ljdk3/AllStructures$1; L0 L1 4
+ MAXSTACK = 4
+ MAXLOCALS = 5
+
+ // access flags 0x1008
+ static synthetic access$300(Ljdk3/AllStructures$InnerClass;)D
+ L0
+ LINENUMBER 47 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures$InnerClass.f0 : D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk3/AllStructures$InnerClass; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk3.AllStructures.txt b/asm-util/src/test/resources/jdk3.AllStructures.txt
new file mode 100644
index 00000000..cd8cf5d5
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.AllStructures.txt
@@ -0,0 +1,252 @@
+// class version 45.3 (196653)
+// access flags 0x420
+abstract class jdk3/AllStructures implements java/lang/Runnable java/lang/Cloneable java/io/Serializable {
+
+ // compiled from: AllStructures.java
+ // access flags 0x2
+ private INNERCLASS jdk3/AllStructures$InnerClass jdk3/AllStructures InnerClass
+ // access flags 0x0
+ INNERCLASS jdk3/AllStructures$1 null null
+
+ // access flags 0x1A
+ private final static Ljava/lang/String; UTF8 = "€ࠀ耀"
+
+ // access flags 0x1A
+ private final static J serialVersionUID = 123456
+
+ // access flags 0x1
+ public I f0
+
+ // access flags 0x4
+ protected F f1
+
+ // access flags 0x0
+ J f2
+
+ // access flags 0x2
+ private D f3
+
+ // access flags 0x8
+ static Ljdk3/AllStructures; f4
+
+ // access flags 0x10
+ final B f5 = 1
+
+ // access flags 0x80
+ transient C f6
+
+ // access flags 0x40
+ volatile S f7
+
+ // access flags 0x0
+ Z f8
+
+ // access flags 0x0
+ <init>()V
+ L0
+ LINENUMBER 7 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ L1
+ LINENUMBER 17 L1
+ ALOAD 0
+ ICONST_1
+ PUTFIELD jdk3/AllStructures.f5 : B
+ L2
+ LINENUMBER 7 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public m0()I
+ L0
+ LINENUMBER 27 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f0 : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x4
+ protected m1()F
+ L0
+ LINENUMBER 31 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f1 : F
+ FRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x0
+ m2()J
+ L0
+ LINENUMBER 35 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f2 : J
+ LRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x2
+ private m3()D
+ L0
+ LINENUMBER 39 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f3 : D
+ DRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x8
+ static m4()Ljdk3/AllStructures;
+ L0
+ LINENUMBER 43 L0
+ GETSTATIC jdk3/AllStructures.f4 : Ljdk3/AllStructures;
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 0
+
+ // access flags 0x10
+ final m5()B
+ L0
+ LINENUMBER 47 L0
+ ICONST_1
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x800
+ strictfp m6()C
+ L0
+ LINENUMBER 51 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f6 : C
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x0
+ m7()S
+ L0
+ LINENUMBER 55 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f7 : S
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x400
+ abstract m8()Z
+
+ // access flags 0x9
+ public static main([Ljava/lang/String;)V
+ L0
+ LINENUMBER 60 L0
+ RETURN
+ L1
+ LOCALVARIABLE args [Ljava/lang/String; L0 L1 0
+ MAXSTACK = 0
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public run()V
+ L0
+ LINENUMBER 62 L0
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 0
+ MAXLOCALS = 1
+
+ // access flags 0x21
+ public synchronized clone()Ljava/lang/Object;
+ L0
+ LINENUMBER 65 L0
+ ALOAD 0
+ ARETURN
+ L1
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x102
+ private native nativeMethod()V
+
+ // access flags 0x2
+ private anonymousInnerClass()Ljava/lang/Runnable; throws java/lang/Exception
+ L0
+ LINENUMBER 71 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f0 : I
+ IFLE L1
+ L2
+ LINENUMBER 72 L2
+ NEW java/lang/Exception
+ DUP
+ INVOKESPECIAL java/lang/Exception.<init> ()V
+ ATHROW
+ L1
+ LINENUMBER 73 L1
+ NEW jdk3/AllStructures$1
+ DUP
+ ALOAD 0
+ INVOKESPECIAL jdk3/AllStructures$1.<init> (Ljdk3/AllStructures;)V
+ ARETURN
+ L3
+ LOCALVARIABLE this Ljdk3/AllStructures; L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x1008
+ static synthetic access$000(Ljdk3/AllStructures;)D
+ L0
+ LINENUMBER 7 L0
+ ALOAD 0
+ GETFIELD jdk3/AllStructures.f3 : D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x1008
+ static synthetic access$100(Ljdk3/AllStructures;)D
+ L0
+ LINENUMBER 7 L0
+ ALOAD 0
+ INVOKESPECIAL jdk3/AllStructures.m3 ()D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk3/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x8
+ static <clinit>()V
+ L0
+ LINENUMBER 23 L0
+ ACONST_NULL
+ PUTSTATIC jdk3/AllStructures.f4 : Ljdk3/AllStructures;
+ L1
+ LINENUMBER 22 L1
+ RETURN
+ MAXSTACK = 1
+ MAXLOCALS = 0
+}
diff --git a/asm-util/src/test/resources/jdk3.ArtificialStructures.txt b/asm-util/src/test/resources/jdk3.ArtificialStructures.txt
new file mode 100644
index 00000000..ae5c1aa9
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.ArtificialStructures.txt
@@ -0,0 +1,101 @@
+// class version 47.0 (47)
+// access flags 0x21
+public class jdk3/ArtificialStructures {
+
+ // compiled from: ArtificialStructures.java
+ // debug info: source-debug
+
+ ATTRIBUTE Comment : unknown
+
+ // access flags 0x1001
+ public synthetic I f
+ ATTRIBUTE Comment : unknown
+
+ // access flags 0x1001
+ public synthetic <init>(Ljava/lang/String;)V
+ ATTRIBUTE Comment : unknown
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ NOP
+ RETURN
+ ATTRIBUTE CodeComment : unknown
+ MAXSTACK = 1
+ MAXLOCALS = 2
+
+ // access flags 0x0
+ <init>(Z)V
+ ILOAD 1
+ ALOAD 0
+ SWAP
+ IFEQ L0
+ LDC "1"
+ GOTO L1
+ L0
+ LINENUMBER 1 L0
+ LINENUMBER 3 L0
+ FRAME FULL [U I] [U]
+ LDC "0"
+ L1
+ LINENUMBER 5 L1
+ LINENUMBER 7 L1
+ LINENUMBER 11 L1
+ LINENUMBER 13 L1
+ LINENUMBER 17 L1
+ FRAME FULL [U I] [U java/lang/String]
+ INVOKESPECIAL jdk3/ArtificialStructures.<init> (Ljava/lang/String;)V
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x8
+ static dup_x2(IJ)V
+ LLOAD 1
+ ILOAD 0
+ DUP_X2
+ I2L
+ LADD
+ INVOKESTATIC jdk3/ArtificialStructures.dup_x2 (IJ)V
+ RETURN
+ MAXSTACK = 5
+ MAXLOCALS = 3
+
+ // access flags 0x8
+ static dup2_x2(IIII)V
+ ILOAD 3
+ ILOAD 2
+ ILOAD 1
+ ILOAD 0
+ DUP2_X2
+ IADD
+ IADD
+ INVOKESTATIC jdk3/ArtificialStructures.dup2_x2 (IIII)V
+ RETURN
+ MAXSTACK = 6
+ MAXLOCALS = 4
+
+ // access flags 0x8
+ static dup2_x2(IIJ)V
+ LLOAD 2
+ ILOAD 1
+ ILOAD 0
+ DUP2_X2
+ IADD
+ I2L
+ LADD
+ INVOKESTATIC jdk3/ArtificialStructures.dup2_x2 (IIJ)V
+ RETURN
+ MAXSTACK = 6
+ MAXLOCALS = 4
+
+ // access flags 0x8
+ static dup2_x2(JD)V
+ DLOAD 2
+ LLOAD 0
+ DUP2_X2
+ L2D
+ DADD
+ INVOKESTATIC jdk3/ArtificialStructures.dup2_x2 (JD)V
+ RETURN
+ MAXSTACK = 6
+ MAXLOCALS = 4
+}
diff --git a/asm-util/src/test/resources/jdk3.SubOptimalMaxStackAndLocals.txt b/asm-util/src/test/resources/jdk3.SubOptimalMaxStackAndLocals.txt
new file mode 100644
index 00000000..c349b069
--- /dev/null
+++ b/asm-util/src/test/resources/jdk3.SubOptimalMaxStackAndLocals.txt
@@ -0,0 +1,14 @@
+// class version 47.0 (47)
+// access flags 0x21
+public class jdk3/SubOptimalMaxStackAndLocals {
+
+ // compiled from: SubOptimalMaxStackAndLocals.jasm
+
+ // access flags 0x1
+ public <init>()V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 3
+}
diff --git a/asm-util/src/test/resources/jdk5.AllInstructions.txt b/asm-util/src/test/resources/jdk5.AllInstructions.txt
new file mode 100644
index 00000000..94cb8a04
--- /dev/null
+++ b/asm-util/src/test/resources/jdk5.AllInstructions.txt
@@ -0,0 +1,1695 @@
+// class version 49.0 (49)
+// access flags 0x20
+class jdk5/AllInstructions {
+
+ // compiled from: AllInstructions.java
+
+ // access flags 0x2
+ private Ljava/lang/Class; c
+
+ // access flags 0x2
+ private Ljava/lang/Class; d
+
+ // access flags 0x2
+ private I f
+
+ // access flags 0x2
+ private J g
+
+ // access flags 0x2
+ private Ljdk5/AllInstructions; field
+
+ // access flags 0xA
+ private static Ljdk5/AllInstructions; staticField
+
+ // access flags 0x0
+ <init>()V
+ L0
+ LINENUMBER 45 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x0
+ <init>(IFJDLjava/lang/Object;)V
+ L0
+ LINENUMBER 47 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L1 0
+ LOCALVARIABLE v0 I L0 L1 1
+ LOCALVARIABLE v1 F L0 L1 2
+ LOCALVARIABLE v2 J L0 L1 3
+ LOCALVARIABLE v3 D L0 L1 5
+ LOCALVARIABLE v4 Ljava/lang/Object; L0 L1 7
+ MAXSTACK = 1
+ MAXLOCALS = 8
+
+ // access flags 0x1
+ public ldcWithClassConstant()V
+ L0
+ LINENUMBER 51 L0
+ ALOAD 0
+ LDC Ljdk5/AllInstructions;.class
+ PUTFIELD jdk5/AllInstructions.c : Ljava/lang/Class;
+ L1
+ LINENUMBER 52 L1
+ ALOAD 0
+ LDC [Ljdk5/AllInstructions;.class
+ PUTFIELD jdk5/AllInstructions.d : Ljava/lang/Class;
+ L2
+ LINENUMBER 53 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static intInstructions(IIIIIIIII)I
+ L0
+ LINENUMBER 57 L0
+ ILOAD 0
+ ICONST_M1
+ IF_ICMPGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 9
+ L3
+ LINENUMBER 58 L3
+ ILOAD 1
+ ICONST_1
+ IF_ICMPLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 10
+ L6
+ LINENUMBER 59 L6
+ ILOAD 2
+ ICONST_2
+ IF_ICMPGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 11
+ L9
+ LINENUMBER 60 L9
+ ILOAD 3
+ ICONST_3
+ IF_ICMPLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 12
+ L12
+ LINENUMBER 61 L12
+ ILOAD 4
+ ICONST_4
+ IF_ICMPNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 13
+ L15
+ LINENUMBER 62 L15
+ ILOAD 5
+ ICONST_5
+ IF_ICMPEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 14
+ L18
+ LINENUMBER 63 L18
+ ILOAD 9
+ IFEQ L19
+ ILOAD 6
+ ICONST_5
+ IADD
+ GOTO L20
+ L19
+ ILOAD 6
+ ICONST_5
+ ISUB
+ L20
+ ISTORE 0
+ L21
+ LINENUMBER 64 L21
+ ILOAD 10
+ IFEQ L22
+ ILOAD 7
+ BIPUSH 100
+ IMUL
+ GOTO L23
+ L22
+ ILOAD 7
+ BIPUSH 100
+ IDIV
+ L23
+ ISTORE 1
+ L24
+ LINENUMBER 65 L24
+ ILOAD 11
+ IFEQ L25
+ ILOAD 8
+ SIPUSH 10000
+ IREM
+ GOTO L26
+ L25
+ ILOAD 8
+ ICONST_M1
+ IXOR
+ L26
+ ISTORE 2
+ L27
+ LINENUMBER 66 L27
+ ILOAD 12
+ IFEQ L28
+ ILOAD 0
+ LDC 1000000
+ IAND
+ GOTO L29
+ L28
+ ILOAD 0
+ LDC 1000000
+ IOR
+ L29
+ ISTORE 3
+ L30
+ LINENUMBER 67 L30
+ ILOAD 13
+ IFEQ L31
+ ILOAD 1
+ ILOAD 2
+ IXOR
+ GOTO L32
+ L31
+ ILOAD 1
+ ILOAD 2
+ ISHL
+ L32
+ ISTORE 4
+ L33
+ LINENUMBER 68 L33
+ ILOAD 14
+ IFEQ L34
+ ILOAD 2
+ ILOAD 3
+ ISHR
+ GOTO L35
+ L34
+ ILOAD 2
+ ILOAD 3
+ IUSHR
+ L35
+ ISTORE 5
+ L36
+ LINENUMBER 69 L36
+ IINC 6 1
+ L37
+ LINENUMBER 70 L37
+ ILOAD 6
+ IFGE L38
+ ILOAD 6
+ INEG
+ GOTO L39
+ L38
+ ILOAD 6
+ L39
+ ISTORE 7
+ L40
+ LINENUMBER 71 L40
+ ILOAD 0
+ IFGE L41
+ ILOAD 1
+ GOTO L42
+ L41
+ ILOAD 2
+ L42
+ ISTORE 1
+ L43
+ LINENUMBER 72 L43
+ ILOAD 1
+ IFLE L44
+ ILOAD 2
+ GOTO L45
+ L44
+ ILOAD 3
+ L45
+ ISTORE 2
+ L46
+ LINENUMBER 73 L46
+ ILOAD 2
+ IFGT L47
+ ILOAD 3
+ GOTO L48
+ L47
+ ILOAD 4
+ L48
+ ISTORE 3
+ L49
+ LINENUMBER 74 L49
+ ILOAD 3
+ IFLT L50
+ ILOAD 4
+ GOTO L51
+ L50
+ ILOAD 5
+ L51
+ ISTORE 4
+ L52
+ LINENUMBER 75 L52
+ ILOAD 4
+ IFNE L53
+ ILOAD 5
+ GOTO L54
+ L53
+ ILOAD 6
+ L54
+ ISTORE 5
+ L55
+ LINENUMBER 76 L55
+ ILOAD 5
+ IFEQ L56
+ ILOAD 6
+ GOTO L57
+ L56
+ ILOAD 7
+ L57
+ ISTORE 6
+ L58
+ LINENUMBER 77 L58
+ ILOAD 0
+ ILOAD 1
+ IADD
+ ILOAD 2
+ IADD
+ ILOAD 3
+ IADD
+ ILOAD 4
+ IADD
+ ILOAD 5
+ IADD
+ ILOAD 6
+ IADD
+ ILOAD 7
+ IADD
+ ILOAD 8
+ IADD
+ IRETURN
+ L59
+ LOCALVARIABLE v0 I L0 L59 0
+ LOCALVARIABLE v1 I L0 L59 1
+ LOCALVARIABLE v2 I L0 L59 2
+ LOCALVARIABLE v3 I L0 L59 3
+ LOCALVARIABLE v4 I L0 L59 4
+ LOCALVARIABLE v5 I L0 L59 5
+ LOCALVARIABLE v6 I L0 L59 6
+ LOCALVARIABLE v7 I L0 L59 7
+ LOCALVARIABLE v8 I L0 L59 8
+ LOCALVARIABLE b0 Z L3 L59 9
+ LOCALVARIABLE b1 Z L6 L59 10
+ LOCALVARIABLE b2 Z L9 L59 11
+ LOCALVARIABLE b3 Z L12 L59 12
+ LOCALVARIABLE b4 Z L15 L59 13
+ LOCALVARIABLE b5 Z L18 L59 14
+ MAXSTACK = 2
+ MAXLOCALS = 15
+
+ // access flags 0x9
+ public static longInstructions(JJJJJJJJJ)J
+ L0
+ LINENUMBER 82 L0
+ LLOAD 0
+ LDC -1
+ LCMP
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 18
+ L3
+ LINENUMBER 83 L3
+ LLOAD 2
+ LCONST_1
+ LCMP
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 19
+ L6
+ LINENUMBER 84 L6
+ LLOAD 4
+ LDC 2
+ LCMP
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 20
+ L9
+ LINENUMBER 85 L9
+ LLOAD 6
+ LDC 3
+ LCMP
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 21
+ L12
+ LINENUMBER 86 L12
+ LLOAD 8
+ LDC 4
+ LCMP
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 22
+ L15
+ LINENUMBER 87 L15
+ LLOAD 10
+ LDC 5
+ LCMP
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 23
+ L18
+ LINENUMBER 88 L18
+ ILOAD 18
+ IFEQ L19
+ LLOAD 12
+ LDC 5
+ LADD
+ GOTO L20
+ L19
+ LLOAD 12
+ LDC 5
+ LSUB
+ L20
+ LSTORE 0
+ L21
+ LINENUMBER 89 L21
+ ILOAD 19
+ IFEQ L22
+ LLOAD 14
+ LDC 100
+ LMUL
+ GOTO L23
+ L22
+ LLOAD 14
+ LDC 100
+ LDIV
+ L23
+ LSTORE 2
+ L24
+ LINENUMBER 90 L24
+ ILOAD 20
+ IFEQ L25
+ LLOAD 16
+ LDC 10000
+ LREM
+ GOTO L26
+ L25
+ LLOAD 16
+ LDC -1
+ LXOR
+ L26
+ LSTORE 4
+ L27
+ LINENUMBER 91 L27
+ ILOAD 21
+ IFEQ L28
+ LLOAD 0
+ LDC 1000000
+ LAND
+ GOTO L29
+ L28
+ LLOAD 0
+ LDC 1000000
+ LOR
+ L29
+ LSTORE 6
+ L30
+ LINENUMBER 92 L30
+ ILOAD 22
+ IFEQ L31
+ LLOAD 2
+ LLOAD 4
+ LXOR
+ GOTO L32
+ L31
+ LLOAD 2
+ LLOAD 4
+ L2I
+ LSHL
+ L32
+ LSTORE 8
+ L33
+ LINENUMBER 93 L33
+ ILOAD 23
+ IFEQ L34
+ LLOAD 4
+ LLOAD 6
+ L2I
+ LSHR
+ GOTO L35
+ L34
+ LLOAD 4
+ LLOAD 6
+ L2I
+ LUSHR
+ L35
+ LSTORE 10
+ L36
+ LINENUMBER 94 L36
+ LLOAD 12
+ LCONST_1
+ LADD
+ LSTORE 12
+ L37
+ LINENUMBER 95 L37
+ LLOAD 12
+ LCONST_0
+ LCMP
+ IFGE L38
+ LLOAD 12
+ LNEG
+ GOTO L39
+ L38
+ LLOAD 12
+ L39
+ LSTORE 14
+ L40
+ LINENUMBER 96 L40
+ LLOAD 0
+ LLOAD 2
+ LADD
+ LLOAD 4
+ LADD
+ LLOAD 6
+ LADD
+ LLOAD 8
+ LADD
+ LLOAD 10
+ LADD
+ LLOAD 12
+ LADD
+ LLOAD 14
+ LADD
+ LLOAD 16
+ LADD
+ LRETURN
+ L41
+ LOCALVARIABLE v0 J L0 L41 0
+ LOCALVARIABLE v1 J L0 L41 2
+ LOCALVARIABLE v2 J L0 L41 4
+ LOCALVARIABLE v3 J L0 L41 6
+ LOCALVARIABLE v4 J L0 L41 8
+ LOCALVARIABLE v5 J L0 L41 10
+ LOCALVARIABLE v6 J L0 L41 12
+ LOCALVARIABLE v7 J L0 L41 14
+ LOCALVARIABLE v8 J L0 L41 16
+ LOCALVARIABLE b0 Z L3 L41 18
+ LOCALVARIABLE b1 Z L6 L41 19
+ LOCALVARIABLE b2 Z L9 L41 20
+ LOCALVARIABLE b3 Z L12 L41 21
+ LOCALVARIABLE b4 Z L15 L41 22
+ LOCALVARIABLE b5 Z L18 L41 23
+ MAXSTACK = 4
+ MAXLOCALS = 24
+
+ // access flags 0x9
+ public static floatInstructions(FFFFFFFFF)F
+ L0
+ LINENUMBER 101 L0
+ FLOAD 0
+ LDC -1.0
+ FCMPG
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 9
+ L3
+ LINENUMBER 102 L3
+ FLOAD 1
+ FCONST_1
+ FCMPL
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 10
+ L6
+ LINENUMBER 103 L6
+ FLOAD 2
+ FCONST_2
+ FCMPG
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 11
+ L9
+ LINENUMBER 104 L9
+ FLOAD 3
+ LDC 3.0
+ FCMPL
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 12
+ L12
+ LINENUMBER 105 L12
+ FLOAD 4
+ LDC 4.0
+ FCMPL
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 13
+ L15
+ LINENUMBER 106 L15
+ FLOAD 5
+ LDC 5.0
+ FCMPL
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 14
+ L18
+ LINENUMBER 107 L18
+ ILOAD 9
+ IFEQ L19
+ FLOAD 6
+ LDC 5.0
+ FADD
+ GOTO L20
+ L19
+ FLOAD 6
+ LDC 5.0
+ FSUB
+ L20
+ FSTORE 0
+ L21
+ LINENUMBER 108 L21
+ ILOAD 10
+ IFEQ L22
+ FLOAD 7
+ LDC 100.0
+ FMUL
+ GOTO L23
+ L22
+ FLOAD 7
+ LDC 100.0
+ FDIV
+ L23
+ FSTORE 1
+ L24
+ LINENUMBER 109 L24
+ ILOAD 11
+ IFEQ L25
+ FLOAD 8
+ LDC 10000.0
+ FREM
+ GOTO L26
+ L25
+ FLOAD 8
+ L26
+ FSTORE 2
+ L27
+ LINENUMBER 110 L27
+ ILOAD 12
+ IFEQ L28
+ FLOAD 3
+ FNEG
+ GOTO L29
+ L28
+ FLOAD 3
+ L29
+ FSTORE 3
+ L30
+ LINENUMBER 111 L30
+ ILOAD 13
+ IFEQ L31
+ FLOAD 4
+ FNEG
+ GOTO L32
+ L31
+ FLOAD 4
+ L32
+ FSTORE 4
+ L33
+ LINENUMBER 112 L33
+ ILOAD 14
+ IFEQ L34
+ FLOAD 5
+ FNEG
+ GOTO L35
+ L34
+ FLOAD 5
+ L35
+ FSTORE 5
+ L36
+ LINENUMBER 113 L36
+ FLOAD 6
+ FCONST_1
+ FADD
+ FSTORE 6
+ L37
+ LINENUMBER 114 L37
+ FLOAD 6
+ FCONST_0
+ FCMPG
+ IFGE L38
+ FLOAD 6
+ FNEG
+ GOTO L39
+ L38
+ FLOAD 6
+ L39
+ FSTORE 7
+ L40
+ LINENUMBER 115 L40
+ FLOAD 7
+ FSTORE 8
+ L41
+ LINENUMBER 116 L41
+ FLOAD 0
+ FLOAD 1
+ FADD
+ FLOAD 2
+ FADD
+ FLOAD 3
+ FADD
+ FLOAD 4
+ FADD
+ FLOAD 5
+ FADD
+ FLOAD 6
+ FADD
+ FLOAD 7
+ FADD
+ FLOAD 8
+ FADD
+ FRETURN
+ L42
+ LOCALVARIABLE v0 F L0 L42 0
+ LOCALVARIABLE v1 F L0 L42 1
+ LOCALVARIABLE v2 F L0 L42 2
+ LOCALVARIABLE v3 F L0 L42 3
+ LOCALVARIABLE v4 F L0 L42 4
+ LOCALVARIABLE v5 F L0 L42 5
+ LOCALVARIABLE v6 F L0 L42 6
+ LOCALVARIABLE v7 F L0 L42 7
+ LOCALVARIABLE v8 F L0 L42 8
+ LOCALVARIABLE b0 Z L3 L42 9
+ LOCALVARIABLE b1 Z L6 L42 10
+ LOCALVARIABLE b2 Z L9 L42 11
+ LOCALVARIABLE b3 Z L12 L42 12
+ LOCALVARIABLE b4 Z L15 L42 13
+ LOCALVARIABLE b5 Z L18 L42 14
+ MAXSTACK = 2
+ MAXLOCALS = 15
+
+ // access flags 0x9
+ public static doubleInstructions(DDDDDDDDD)D
+ L0
+ LINENUMBER 129 L0
+ DLOAD 0
+ LDC -1.0
+ DCMPG
+ IFGE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 18
+ L3
+ LINENUMBER 130 L3
+ DLOAD 2
+ DCONST_1
+ DCMPL
+ IFLE L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 19
+ L6
+ LINENUMBER 131 L6
+ DLOAD 4
+ LDC 2.0
+ DCMPG
+ IFGT L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 20
+ L9
+ LINENUMBER 132 L9
+ DLOAD 6
+ LDC 3.0
+ DCMPL
+ IFLT L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 21
+ L12
+ LINENUMBER 133 L12
+ DLOAD 8
+ LDC 4.0
+ DCMPL
+ IFNE L13
+ ICONST_1
+ GOTO L14
+ L13
+ ICONST_0
+ L14
+ ISTORE 22
+ L15
+ LINENUMBER 134 L15
+ DLOAD 10
+ LDC 5.0
+ DCMPL
+ IFEQ L16
+ ICONST_1
+ GOTO L17
+ L16
+ ICONST_0
+ L17
+ ISTORE 23
+ L18
+ LINENUMBER 135 L18
+ ILOAD 18
+ IFEQ L19
+ DLOAD 12
+ LDC 5.0
+ DADD
+ GOTO L20
+ L19
+ DLOAD 12
+ LDC 5.0
+ DSUB
+ L20
+ DSTORE 0
+ L21
+ LINENUMBER 136 L21
+ ILOAD 19
+ IFEQ L22
+ DLOAD 14
+ LDC 100.0
+ DMUL
+ GOTO L23
+ L22
+ DLOAD 14
+ LDC 100.0
+ DDIV
+ L23
+ DSTORE 2
+ L24
+ LINENUMBER 137 L24
+ ILOAD 20
+ IFEQ L25
+ DLOAD 16
+ LDC 10000.0
+ DREM
+ GOTO L26
+ L25
+ DLOAD 16
+ L26
+ DSTORE 4
+ L27
+ LINENUMBER 138 L27
+ ILOAD 21
+ IFEQ L28
+ DLOAD 6
+ DNEG
+ GOTO L29
+ L28
+ DLOAD 6
+ L29
+ DSTORE 6
+ L30
+ LINENUMBER 139 L30
+ ILOAD 22
+ IFEQ L31
+ DLOAD 8
+ DNEG
+ GOTO L32
+ L31
+ DLOAD 8
+ L32
+ DSTORE 8
+ L33
+ LINENUMBER 140 L33
+ ILOAD 23
+ IFEQ L34
+ DLOAD 10
+ DNEG
+ GOTO L35
+ L34
+ DLOAD 10
+ L35
+ DSTORE 10
+ L36
+ LINENUMBER 141 L36
+ DLOAD 12
+ DCONST_1
+ DADD
+ DSTORE 12
+ L37
+ LINENUMBER 142 L37
+ DLOAD 12
+ DCONST_0
+ DCMPG
+ IFGE L38
+ DLOAD 12
+ DNEG
+ GOTO L39
+ L38
+ DLOAD 12
+ L39
+ DSTORE 14
+ L40
+ LINENUMBER 143 L40
+ DLOAD 0
+ DLOAD 2
+ DADD
+ DLOAD 4
+ DADD
+ DLOAD 6
+ DADD
+ DLOAD 8
+ DADD
+ DLOAD 10
+ DADD
+ DLOAD 12
+ DADD
+ DLOAD 14
+ DADD
+ DLOAD 16
+ DADD
+ DRETURN
+ L41
+ LOCALVARIABLE v0 D L0 L41 0
+ LOCALVARIABLE v1 D L0 L41 2
+ LOCALVARIABLE v2 D L0 L41 4
+ LOCALVARIABLE v3 D L0 L41 6
+ LOCALVARIABLE v4 D L0 L41 8
+ LOCALVARIABLE v5 D L0 L41 10
+ LOCALVARIABLE v6 D L0 L41 12
+ LOCALVARIABLE v7 D L0 L41 14
+ LOCALVARIABLE v8 D L0 L41 16
+ LOCALVARIABLE b0 Z L3 L41 18
+ LOCALVARIABLE b1 Z L6 L41 19
+ LOCALVARIABLE b2 Z L9 L41 20
+ LOCALVARIABLE b3 Z L12 L41 21
+ LOCALVARIABLE b4 Z L15 L41 22
+ LOCALVARIABLE b5 Z L18 L41 23
+ MAXSTACK = 4
+ MAXLOCALS = 24
+
+ // access flags 0x9
+ public static castInstructions(IJJ)D
+ L0
+ LINENUMBER 147 L0
+ ILOAD 0
+ I2B
+ ISTORE 5
+ L1
+ LINENUMBER 148 L1
+ LLOAD 1
+ L2I
+ I2C
+ ISTORE 6
+ L2
+ LINENUMBER 149 L2
+ LLOAD 3
+ L2I
+ I2S
+ ISTORE 7
+ L3
+ LINENUMBER 150 L3
+ ILOAD 5
+ I2L
+ LSTORE 8
+ L4
+ LINENUMBER 151 L4
+ ILOAD 6
+ I2F
+ FSTORE 10
+ L5
+ LINENUMBER 152 L5
+ ILOAD 7
+ I2D
+ DSTORE 11
+ L6
+ LINENUMBER 153 L6
+ LLOAD 8
+ LSTORE 1
+ L7
+ LINENUMBER 154 L7
+ LLOAD 1
+ LSTORE 3
+ L8
+ LINENUMBER 155 L8
+ DLOAD 11
+ D2L
+ LSTORE 8
+ L9
+ LINENUMBER 156 L9
+ ILOAD 0
+ I2L
+ LLOAD 1
+ LADD
+ LLOAD 3
+ LADD
+ ILOAD 5
+ I2L
+ LADD
+ ILOAD 6
+ I2L
+ LADD
+ ILOAD 7
+ I2L
+ LADD
+ LLOAD 8
+ LADD
+ L2F
+ FLOAD 10
+ FADD
+ F2D
+ DLOAD 11
+ DADD
+ DRETURN
+ L10
+ LOCALVARIABLE v0 I L0 L10 0
+ LOCALVARIABLE v1 J L0 L10 1
+ LOCALVARIABLE v2 J L0 L10 3
+ LOCALVARIABLE v3 B L1 L10 5
+ LOCALVARIABLE v4 C L2 L10 6
+ LOCALVARIABLE v5 S L3 L10 7
+ LOCALVARIABLE v6 J L4 L10 8
+ LOCALVARIABLE v7 F L5 L10 10
+ LOCALVARIABLE v8 D L6 L10 11
+ MAXSTACK = 4
+ MAXLOCALS = 13
+
+ // access flags 0x9
+ public static castInstructions(FDD)F
+ L0
+ LINENUMBER 160 L0
+ FLOAD 0
+ F2I
+ I2B
+ ISTORE 5
+ L1
+ LINENUMBER 161 L1
+ DLOAD 1
+ D2I
+ I2C
+ ISTORE 6
+ L2
+ LINENUMBER 162 L2
+ DLOAD 3
+ D2I
+ I2S
+ ISTORE 7
+ L3
+ LINENUMBER 163 L3
+ ILOAD 5
+ I2L
+ LSTORE 8
+ L4
+ LINENUMBER 164 L4
+ ILOAD 6
+ I2F
+ FSTORE 10
+ L5
+ LINENUMBER 165 L5
+ ILOAD 7
+ I2D
+ DSTORE 11
+ L6
+ LINENUMBER 166 L6
+ LLOAD 8
+ L2D
+ DSTORE 1
+ L7
+ LINENUMBER 167 L7
+ DLOAD 1
+ DSTORE 3
+ L8
+ LINENUMBER 168 L8
+ FLOAD 10
+ F2L
+ LSTORE 8
+ L9
+ LINENUMBER 169 L9
+ FLOAD 0
+ F2D
+ DLOAD 1
+ DADD
+ DLOAD 3
+ DADD
+ ILOAD 5
+ I2D
+ DADD
+ ILOAD 6
+ I2D
+ DADD
+ ILOAD 7
+ I2D
+ DADD
+ LLOAD 8
+ L2D
+ DADD
+ FLOAD 10
+ F2D
+ DADD
+ DLOAD 11
+ DADD
+ D2F
+ FRETURN
+ L10
+ LOCALVARIABLE v0 F L0 L10 0
+ LOCALVARIABLE v1 D L0 L10 1
+ LOCALVARIABLE v2 D L0 L10 3
+ LOCALVARIABLE v3 B L1 L10 5
+ LOCALVARIABLE v4 C L2 L10 6
+ LOCALVARIABLE v5 S L3 L10 7
+ LOCALVARIABLE v6 J L4 L10 8
+ LOCALVARIABLE v7 F L5 L10 10
+ LOCALVARIABLE v8 D L6 L10 11
+ MAXSTACK = 4
+ MAXLOCALS = 13
+
+ // access flags 0x9
+ public static objectInstructions(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+ L0
+ LINENUMBER 173 L0
+ ALOAD 0
+ ALOAD 1
+ IF_ACMPNE L1
+ ICONST_1
+ GOTO L2
+ L1
+ ICONST_0
+ L2
+ ISTORE 5
+ L3
+ LINENUMBER 174 L3
+ ALOAD 1
+ ALOAD 2
+ IF_ACMPEQ L4
+ ICONST_1
+ GOTO L5
+ L4
+ ICONST_0
+ L5
+ ISTORE 6
+ L6
+ LINENUMBER 175 L6
+ ALOAD 2
+ IFNONNULL L7
+ ICONST_1
+ GOTO L8
+ L7
+ ICONST_0
+ L8
+ ISTORE 7
+ L9
+ LINENUMBER 176 L9
+ ALOAD 3
+ IFNULL L10
+ ICONST_1
+ GOTO L11
+ L10
+ ICONST_0
+ L11
+ ISTORE 8
+ L12
+ LINENUMBER 177 L12
+ ALOAD 4
+ INSTANCEOF java/lang/String
+ ISTORE 9
+ L13
+ LINENUMBER 178 L13
+ ILOAD 5
+ IFEQ L14
+ ACONST_NULL
+ GOTO L15
+ L14
+ ALOAD 0
+ L15
+ ASTORE 0
+ L16
+ LINENUMBER 179 L16
+ ILOAD 6
+ IFEQ L17
+ ALOAD 1
+ GOTO L18
+ L17
+ ALOAD 0
+ L18
+ ASTORE 1
+ L19
+ LINENUMBER 180 L19
+ ILOAD 7
+ IFEQ L20
+ ALOAD 2
+ GOTO L21
+ L20
+ ALOAD 1
+ L21
+ ASTORE 2
+ L22
+ LINENUMBER 181 L22
+ ILOAD 8
+ IFEQ L23
+ ALOAD 3
+ GOTO L24
+ L23
+ ALOAD 2
+ L24
+ ASTORE 3
+ L25
+ LINENUMBER 182 L25
+ ILOAD 9
+ IFEQ L26
+ NEW java/lang/Integer
+ DUP
+ ALOAD 4
+ CHECKCAST java/lang/String
+ INVOKEVIRTUAL java/lang/String.length ()I
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ GOTO L27
+ L26
+ ALOAD 3
+ L27
+ ASTORE 4
+ L28
+ LINENUMBER 183 L28
+ ALOAD 4
+ ARETURN
+ L29
+ LOCALVARIABLE v0 Ljava/lang/Object; L0 L29 0
+ LOCALVARIABLE v1 Ljava/lang/Object; L0 L29 1
+ LOCALVARIABLE v2 Ljava/lang/Object; L0 L29 2
+ LOCALVARIABLE v3 Ljava/lang/Object; L0 L29 3
+ LOCALVARIABLE v4 Ljava/lang/Object; L0 L29 4
+ LOCALVARIABLE b0 Z L3 L29 5
+ LOCALVARIABLE b1 Z L6 L29 6
+ LOCALVARIABLE b2 Z L9 L29 7
+ LOCALVARIABLE b3 Z L12 L29 8
+ LOCALVARIABLE b4 Z L13 L29 9
+ MAXSTACK = 3
+ MAXLOCALS = 10
+
+ // access flags 0x9
+ public static arrayInstructions([B[C[S[I[J[F[D[Ljava/lang/Object;)[Ljava/lang/Object;
+ L0
+ LINENUMBER 188 L0
+ ALOAD 0
+ ICONST_1
+ ALOAD 0
+ ICONST_0
+ BALOAD
+ BASTORE
+ L1
+ LINENUMBER 189 L1
+ ALOAD 1
+ ICONST_1
+ ALOAD 1
+ ICONST_0
+ CALOAD
+ CASTORE
+ L2
+ LINENUMBER 190 L2
+ ALOAD 2
+ ICONST_1
+ ALOAD 2
+ ICONST_0
+ SALOAD
+ SASTORE
+ L3
+ LINENUMBER 191 L3
+ ALOAD 3
+ ICONST_1
+ ALOAD 3
+ ICONST_0
+ IALOAD
+ IASTORE
+ L4
+ LINENUMBER 192 L4
+ ALOAD 4
+ ICONST_1
+ ALOAD 4
+ ICONST_0
+ LALOAD
+ LASTORE
+ L5
+ LINENUMBER 193 L5
+ ALOAD 5
+ ICONST_1
+ ALOAD 5
+ ICONST_0
+ FALOAD
+ FASTORE
+ L6
+ LINENUMBER 194 L6
+ ALOAD 6
+ ICONST_1
+ ALOAD 6
+ ICONST_0
+ DALOAD
+ DASTORE
+ L7
+ LINENUMBER 195 L7
+ ALOAD 7
+ ICONST_1
+ ALOAD 7
+ ICONST_0
+ AALOAD
+ AASTORE
+ L8
+ LINENUMBER 196 L8
+ ALOAD 7
+ ARRAYLENGTH
+ ANEWARRAY java/lang/Object
+ ASTORE 8
+ L9
+ LINENUMBER 197 L9
+ ALOAD 8
+ ICONST_0
+ ICONST_4
+ BIPUSH 8
+ BIPUSH 16
+ MULTIANEWARRAY [[[I 3
+ AASTORE
+ L10
+ LINENUMBER 198 L10
+ ALOAD 8
+ ARETURN
+ L11
+ LOCALVARIABLE v0 [B L0 L11 0
+ LOCALVARIABLE v1 [C L0 L11 1
+ LOCALVARIABLE v2 [S L0 L11 2
+ LOCALVARIABLE v3 [I L0 L11 3
+ LOCALVARIABLE v4 [J L0 L11 4
+ LOCALVARIABLE v5 [F L0 L11 5
+ LOCALVARIABLE v6 [D L0 L11 6
+ LOCALVARIABLE v7 [Ljava/lang/Object; L0 L11 7
+ LOCALVARIABLE v8 [Ljava/lang/Object; L9 L11 8
+ MAXSTACK = 5
+ MAXLOCALS = 9
+
+ // access flags 0x1
+ public fieldInstructions()V
+ L0
+ LINENUMBER 202 L0
+ ALOAD 0
+ GETFIELD jdk5/AllInstructions.field : Ljdk5/AllInstructions;
+ ASTORE 1
+ L1
+ LINENUMBER 203 L1
+ ALOAD 0
+ GETSTATIC jdk5/AllInstructions.staticField : Ljdk5/AllInstructions;
+ PUTFIELD jdk5/AllInstructions.field : Ljdk5/AllInstructions;
+ L2
+ LINENUMBER 204 L2
+ ALOAD 1
+ PUTSTATIC jdk5/AllInstructions.staticField : Ljdk5/AllInstructions;
+ L3
+ LINENUMBER 205 L3
+ RETURN
+ L4
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L4 0
+ LOCALVARIABLE c Ljdk5/AllInstructions; L1 L4 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public methodInstructions(Ljava/lang/Runnable;)V
+ L0
+ LINENUMBER 208 L0
+ NEW jdk5/AllInstructions
+ DUP
+ INVOKESPECIAL jdk5/AllInstructions.<init> ()V
+ ASTORE 2
+ L1
+ LINENUMBER 209 L1
+ ALOAD 2
+ INVOKEVIRTUAL jdk5/AllInstructions.fieldInstructions ()V
+ L2
+ LINENUMBER 210 L2
+ ALOAD 2
+ INVOKESTATIC jdk5/AllInstructions.monitorInstructions (Ljava/lang/Object;)Ljava/lang/String;
+ POP
+ L3
+ LINENUMBER 211 L3
+ ALOAD 1
+ INVOKEINTERFACE java/lang/Runnable.run ()V (itf)
+ L4
+ LINENUMBER 212 L4
+ RETURN
+ L5
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L5 0
+ LOCALVARIABLE v0 Ljava/lang/Runnable; L0 L5 1
+ LOCALVARIABLE c Ljdk5/AllInstructions; L1 L5 2
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x9
+ public static lookupSwitchInstruction(I)I
+ L0
+ LINENUMBER 215 L0
+ ILOAD 0
+ LOOKUPSWITCH
+ 1000: L1
+ 10000: L2
+ 100000: L3
+ default: L4
+ L1
+ LINENUMBER 217 L1
+ ICONST_1
+ IRETURN
+ L2
+ LINENUMBER 219 L2
+ ICONST_2
+ IRETURN
+ L3
+ LINENUMBER 221 L3
+ ICONST_3
+ IRETURN
+ L4
+ LINENUMBER 223 L4
+ ICONST_M1
+ IRETURN
+ L5
+ LOCALVARIABLE v0 I L0 L5 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static tableSwitchInstruction(I)I
+ L0
+ LINENUMBER 228 L0
+ ILOAD 0
+ TABLESWITCH
+ 0: L1
+ 1: L2
+ 2: L3
+ default: L4
+ L1
+ LINENUMBER 230 L1
+ ICONST_1
+ IRETURN
+ L2
+ LINENUMBER 232 L2
+ ICONST_2
+ IRETURN
+ L3
+ LINENUMBER 234 L3
+ ICONST_3
+ IRETURN
+ L4
+ LINENUMBER 236 L4
+ ICONST_M1
+ IRETURN
+ L5
+ LOCALVARIABLE v0 I L0 L5 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static monitorInstructions(Ljava/lang/Object;)Ljava/lang/String;
+ TRYCATCHBLOCK L0 L1 L2 null
+ TRYCATCHBLOCK L2 L3 L2 null
+ L4
+ LINENUMBER 241 L4
+ ALOAD 0
+ DUP
+ ASTORE 1
+ MONITORENTER
+ L0
+ LINENUMBER 242 L0
+ ALOAD 0
+ INVOKEVIRTUAL java/lang/Object.toString ()Ljava/lang/String;
+ ALOAD 1
+ MONITOREXIT
+ L1
+ ARETURN
+ L2
+ LINENUMBER 243 L2
+ ASTORE 2
+ ALOAD 1
+ MONITOREXIT
+ L3
+ ALOAD 2
+ ATHROW
+ L5
+ LOCALVARIABLE v0 Ljava/lang/Object; L4 L5 0
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public dupX1Instruction()I
+ L0
+ LINENUMBER 247 L0
+ ALOAD 0
+ DUP
+ GETFIELD jdk5/AllInstructions.f : I
+ DUP_X1
+ ICONST_1
+ IADD
+ PUTFIELD jdk5/AllInstructions.f : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L1 0
+ MAXSTACK = 4
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public dup2X1Instruction()J
+ L0
+ LINENUMBER 251 L0
+ ALOAD 0
+ DUP
+ GETFIELD jdk5/AllInstructions.g : J
+ DUP2_X1
+ LCONST_1
+ LADD
+ PUTFIELD jdk5/AllInstructions.g : J
+ LRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L1 0
+ MAXSTACK = 7
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public dupX2Instruction([I[I)V
+ L0
+ LINENUMBER 255 L0
+ ALOAD 1
+ ICONST_0
+ ALOAD 2
+ ICONST_0
+ ICONST_0
+ DUP_X2
+ IASTORE
+ IASTORE
+ L1
+ LINENUMBER 256 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [I L0 L2 1
+ LOCALVARIABLE v1 [I L0 L2 2
+ MAXSTACK = 6
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public dup2X2Instruction([J[J)V
+ L0
+ LINENUMBER 259 L0
+ ALOAD 1
+ ICONST_0
+ ALOAD 2
+ ICONST_0
+ LCONST_0
+ DUP2_X2
+ LASTORE
+ LASTORE
+ L1
+ LINENUMBER 260 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L2 0
+ LOCALVARIABLE v0 [J L0 L2 1
+ LOCALVARIABLE v1 [J L0 L2 2
+ MAXSTACK = 8
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public popInstructions()V
+ L0
+ LINENUMBER 263 L0
+ ALOAD 0
+ INVOKEVIRTUAL jdk5/AllInstructions.dupX1Instruction ()I
+ POP
+ L1
+ LINENUMBER 264 L1
+ ALOAD 0
+ INVOKEVIRTUAL jdk5/AllInstructions.dup2X1Instruction ()J
+ POP2
+ L2
+ LINENUMBER 265 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk5/AllInstructions; L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public jsrAndRetInstructions(I)I throws java/lang/Exception
+ TRYCATCHBLOCK L0 L1 L2 java/lang/Throwable
+ TRYCATCHBLOCK L0 L1 L3 null
+ TRYCATCHBLOCK L2 L4 L3 null
+ TRYCATCHBLOCK L3 L5 L3 null
+ L6
+ LINENUMBER 269 L6
+ ILOAD 1
+ ICONST_1
+ IADD
+ ISTORE 2
+ L0
+ LINENUMBER 271 L0
+ ALOAD 0
+ ILOAD 2
+ INVOKEVIRTUAL jdk5/AllInstructions.jsrAndRetInstructions (I)I
+ ISTORE 2
+ L1
+ LINENUMBER 275 L1
+ IINC 2 1
+ L7
+ LINENUMBER 276 L7
+ GOTO L8
+ L2
+ LINENUMBER 272 L2
+ ASTORE 3
+ L9
+ LINENUMBER 273 L9
+ ICONST_M1
+ ISTORE 4
+ L4
+ LINENUMBER 275 L4
+ IINC 2 1
+ ILOAD 4
+ IRETURN
+ L3
+ ASTORE 5
+ L5
+ IINC 2 1
+ ALOAD 5
+ ATHROW
+ L8
+ LINENUMBER 277 L8
+ ILOAD 2
+ IRETURN
+ L10
+ LOCALVARIABLE t Ljava/lang/Throwable; L9 L3 3
+ LOCALVARIABLE this Ljdk5/AllInstructions; L6 L10 0
+ LOCALVARIABLE v0 I L6 L10 1
+ LOCALVARIABLE u0 I L0 L10 2
+ MAXSTACK = 2
+ MAXLOCALS = 6
+
+ // access flags 0x1
+ public readNullArray()Ljava/lang/Object;
+ TRYCATCHBLOCK L0 L1 L2 java/lang/NullPointerException
+ L3
+ LINENUMBER 281 L3
+ ACONST_NULL
+ ASTORE 1
+ L0
+ LINENUMBER 283 L0
+ ALOAD 1
+ ICONST_0
+ AALOAD
+ L1
+ ARETURN
+ L2
+ LINENUMBER 284 L2
+ ASTORE 2
+ L4
+ LINENUMBER 285 L4
+ ACONST_NULL
+ ARETURN
+ L5
+ LOCALVARIABLE e Ljava/lang/NullPointerException; L4 L5 2
+ LOCALVARIABLE this Ljdk5/AllInstructions; L3 L5 0
+ LOCALVARIABLE array [Ljava/lang/Object; L0 L5 1
+ MAXSTACK = 2
+ MAXLOCALS = 3
+}
diff --git a/asm-util/src/test/resources/jdk5.AllStructures$1LocalClass.txt b/asm-util/src/test/resources/jdk5.AllStructures$1LocalClass.txt
new file mode 100644
index 00000000..30883b98
--- /dev/null
+++ b/asm-util/src/test/resources/jdk5.AllStructures$1LocalClass.txt
@@ -0,0 +1,55 @@
+// class version 49.0 (49)
+// access flags 0x20
+class jdk5/AllStructures$1LocalClass {
+
+ // compiled from: AllStructures.java
+ OUTERCLASS jdk5/AllStructures localClassConstructor (Ljava/lang/String;)V
+ // access flags 0x0
+ INNERCLASS jdk5/AllStructures$1LocalClass null LocalClass
+
+ // access flags 0x1010
+ final synthetic Ljava/lang/String; val$name
+
+ // access flags 0x1010
+ final synthetic Ljdk5/AllStructures; this$0
+
+ // access flags 0x0
+ // signature (I)V
+ // declaration: void <init>(int)
+ <init>(Ljdk5/AllStructures;ILjava/lang/String;)V
+ // annotable parameter count: 1 (visible)
+ @Ljava/lang/Deprecated;() // parameter 0
+ L0
+ LINENUMBER 140 L0
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk5/AllStructures$1LocalClass.this$0 : Ljdk5/AllStructures;
+ ALOAD 0
+ ALOAD 3
+ PUTFIELD jdk5/AllStructures$1LocalClass.val$name : Ljava/lang/String;
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ L1
+ LINENUMBER 141 L1
+ GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
+ NEW java/lang/StringBuilder
+ DUP
+ INVOKESPECIAL java/lang/StringBuilder.<init> ()V
+ ALOAD 0
+ GETFIELD jdk5/AllStructures$1LocalClass.val$name : Ljava/lang/String;
+ INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
+ ILOAD 2
+ INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
+ INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
+ INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
+ L2
+ LINENUMBER 142 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk5/AllStructures$1LocalClass; L0 L3 0
+ // signature Ljdk5/AllStructures.1LocalClass;
+ // declaration: this extends jdk5.AllStructures.1LocalClass
+ LOCALVARIABLE value I L0 L3 2
+ MAXSTACK = 3
+ MAXLOCALS = 4
+}
diff --git a/asm-util/src/test/resources/jdk5.AllStructures$EnumClass.txt b/asm-util/src/test/resources/jdk5.AllStructures$EnumClass.txt
new file mode 100644
index 00000000..8c75d519
--- /dev/null
+++ b/asm-util/src/test/resources/jdk5.AllStructures$EnumClass.txt
@@ -0,0 +1,136 @@
+// class version 49.0 (49)
+// access flags 0x4030
+// signature Ljava/lang/Enum<Ljdk5/AllStructures$EnumClass;>;
+// declaration: jdk5/AllStructures$EnumClass extends java.lang.Enum<jdk5.AllStructures$EnumClass>
+final enum jdk5/AllStructures$EnumClass extends java/lang/Enum {
+
+ // compiled from: AllStructures.java
+ // access flags 0x4018
+ final static enum INNERCLASS jdk5/AllStructures$EnumClass jdk5/AllStructures EnumClass
+
+ // access flags 0x4019
+ public final static enum Ljdk5/AllStructures$EnumClass; VALUE0
+
+ // access flags 0x4019
+ public final static enum Ljdk5/AllStructures$EnumClass; VALUE1
+
+ // access flags 0x4019
+ public final static enum Ljdk5/AllStructures$EnumClass; VALUE2
+
+ // access flags 0x2
+ private I value
+
+ // access flags 0x101A
+ private final static synthetic [Ljdk5/AllStructures$EnumClass; $VALUES
+
+ // access flags 0x19
+ public final static values()[Ljdk5/AllStructures$EnumClass;
+ L0
+ LINENUMBER 200 L0
+ GETSTATIC jdk5/AllStructures$EnumClass.$VALUES : [Ljdk5/AllStructures$EnumClass;
+ INVOKEVIRTUAL [Ljdk5/AllStructures$EnumClass;.clone ()Ljava/lang/Object;
+ CHECKCAST [Ljdk5/AllStructures$EnumClass;
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 0
+
+ // access flags 0x9
+ public static valueOf(Ljava/lang/String;)Ljdk5/AllStructures$EnumClass;
+ L0
+ LINENUMBER 200 L0
+ LDC Ljdk5/AllStructures$EnumClass;.class
+ ALOAD 0
+ INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ CHECKCAST jdk5/AllStructures$EnumClass
+ ARETURN
+ L1
+ LOCALVARIABLE name Ljava/lang/String; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x2
+ // signature (I)V
+ // declaration: void <init>(int)
+ private <init>(Ljava/lang/String;II)V
+ L0
+ LINENUMBER 207 L0
+ ALOAD 0
+ ALOAD 1
+ ILOAD 2
+ INVOKESPECIAL java/lang/Enum.<init> (Ljava/lang/String;I)V
+ L1
+ LINENUMBER 208 L1
+ ALOAD 0
+ ILOAD 3
+ PUTFIELD jdk5/AllStructures$EnumClass.value : I
+ L2
+ LINENUMBER 209 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk5/AllStructures$EnumClass; L0 L3 0
+ LOCALVARIABLE value I L0 L3 3
+ MAXSTACK = 3
+ MAXLOCALS = 4
+
+ // access flags 0x1
+ public getValue()I
+ L0
+ LINENUMBER 212 L0
+ ALOAD 0
+ GETFIELD jdk5/AllStructures$EnumClass.value : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures$EnumClass; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x8
+ static <clinit>()V
+ L0
+ LINENUMBER 201 L0
+ NEW jdk5/AllStructures$EnumClass
+ DUP
+ LDC "VALUE0"
+ ICONST_0
+ ICONST_0
+ INVOKESPECIAL jdk5/AllStructures$EnumClass.<init> (Ljava/lang/String;II)V
+ PUTSTATIC jdk5/AllStructures$EnumClass.VALUE0 : Ljdk5/AllStructures$EnumClass;
+ L1
+ LINENUMBER 202 L1
+ NEW jdk5/AllStructures$EnumClass
+ DUP
+ LDC "VALUE1"
+ ICONST_1
+ ICONST_1
+ INVOKESPECIAL jdk5/AllStructures$EnumClass.<init> (Ljava/lang/String;II)V
+ PUTSTATIC jdk5/AllStructures$EnumClass.VALUE1 : Ljdk5/AllStructures$EnumClass;
+ L2
+ LINENUMBER 203 L2
+ NEW jdk5/AllStructures$EnumClass
+ DUP
+ LDC "VALUE2"
+ ICONST_2
+ ICONST_2
+ INVOKESPECIAL jdk5/AllStructures$EnumClass.<init> (Ljava/lang/String;II)V
+ PUTSTATIC jdk5/AllStructures$EnumClass.VALUE2 : Ljdk5/AllStructures$EnumClass;
+ L3
+ LINENUMBER 200 L3
+ ICONST_3
+ ANEWARRAY jdk5/AllStructures$EnumClass
+ DUP
+ ICONST_0
+ GETSTATIC jdk5/AllStructures$EnumClass.VALUE0 : Ljdk5/AllStructures$EnumClass;
+ AASTORE
+ DUP
+ ICONST_1
+ GETSTATIC jdk5/AllStructures$EnumClass.VALUE1 : Ljdk5/AllStructures$EnumClass;
+ AASTORE
+ DUP
+ ICONST_2
+ GETSTATIC jdk5/AllStructures$EnumClass.VALUE2 : Ljdk5/AllStructures$EnumClass;
+ AASTORE
+ PUTSTATIC jdk5/AllStructures$EnumClass.$VALUES : [Ljdk5/AllStructures$EnumClass;
+ RETURN
+ MAXSTACK = 5
+ MAXLOCALS = 0
+}
diff --git a/asm-util/src/test/resources/jdk5.AllStructures$InvisibleAnnotation.txt b/asm-util/src/test/resources/jdk5.AllStructures$InvisibleAnnotation.txt
new file mode 100644
index 00000000..5746e5bf
--- /dev/null
+++ b/asm-util/src/test/resources/jdk5.AllStructures$InvisibleAnnotation.txt
@@ -0,0 +1,111 @@
+// class version 49.0 (49)
+// access flags 0x2600
+abstract @interface jdk5/AllStructures$InvisibleAnnotation implements java/lang/annotation/Annotation {
+
+ // compiled from: AllStructures.java
+
+ @Ljava/lang/annotation/Retention;(value=Ljava/lang/annotation/RetentionPolicy;.CLASS)
+ // access flags 0x4018
+ final static enum INNERCLASS jdk5/AllStructures$EnumClass jdk5/AllStructures EnumClass
+ // access flags 0x2608
+ static abstract INNERCLASS jdk5/AllStructures$InvisibleAnnotation jdk5/AllStructures InvisibleAnnotation
+
+ // access flags 0x401
+ public abstract byteValue()B
+ default=(byte)1
+
+ // access flags 0x401
+ public abstract charValue()C
+ default=(char)49
+
+ // access flags 0x401
+ public abstract booleanValue()Z
+ default=true
+
+ // access flags 0x401
+ public abstract intValue()I
+ default=1
+
+ // access flags 0x401
+ public abstract shortValue()S
+ default=(short)1
+
+ // access flags 0x401
+ public abstract longValue()J
+ default=1L
+
+ // access flags 0x401
+ public abstract floatValue()F
+ default=1.0F
+
+ // access flags 0x401
+ public abstract doubleValue()D
+ default=1.0D
+
+ // access flags 0x401
+ public abstract stringValue()Ljava/lang/String;
+ default="1"
+
+ // access flags 0x401
+ public abstract classValue()Ljava/lang/Class;
+ default=java.lang.Object.class
+
+ // access flags 0x401
+ public abstract enumValue()Ljdk5/AllStructures$EnumClass;
+ default=Ljdk5/AllStructures$EnumClass;.VALUE1
+
+ // access flags 0x401
+ public abstract annotationValue()Ljava/lang/Deprecated;
+ default=@Ljava/lang/Deprecated;()
+
+ // access flags 0x401
+ public abstract byteArrayValue()[B
+ default={(byte)1}
+
+ // access flags 0x401
+ public abstract charArrayValue()[C
+ default={(char)49}
+
+ // access flags 0x401
+ public abstract booleanArrayValue()[Z
+ default={true}
+
+ // access flags 0x401
+ public abstract intArrayValue()[I
+ default={1}
+
+ // access flags 0x401
+ public abstract shortArrayValue()[S
+ default={(short)1}
+
+ // access flags 0x401
+ public abstract longArrayValue()[J
+ default={1L}
+
+ // access flags 0x401
+ public abstract floatArrayValue()[F
+ default={1.0F}
+
+ // access flags 0x401
+ public abstract doubleArrayValue()[D
+ default={1.0D}
+
+ // access flags 0x401
+ public abstract stringArrayValue()[Ljava/lang/String;
+ default={"1"}
+
+ // access flags 0x401
+ public abstract classArrayValue()[Ljava/lang/Class;
+ default={java.lang.Object.class}
+
+ // access flags 0x401
+ public abstract enumArrayValue()[Ljdk5/AllStructures$EnumClass;
+ default={Ljdk5/AllStructures$EnumClass;.VALUE1}
+
+ // access flags 0x401
+ public abstract annotationArrayValue()[Ljava/lang/Deprecated;
+ default={@Ljava/lang/Deprecated;()}
+
+ // access flags 0x401
+ public abstract otherArrayValue()[I
+}
diff --git a/asm-util/src/test/resources/jdk5.AllStructures.txt b/asm-util/src/test/resources/jdk5.AllStructures.txt
new file mode 100644
index 00000000..24387ab1
--- /dev/null
+++ b/asm-util/src/test/resources/jdk5.AllStructures.txt
@@ -0,0 +1,297 @@
+// class version 49.0 (49)
+// DEPRECATED
+// access flags 0x20020
+// signature <U0:Ljava/lang/Object;U1:Ljava/lang/Number;U2::Ljava/util/List<Ljava/lang/String;>;U3::Ljava/util/List<*>;U4::Ljava/util/List<+Ljava/lang/Number;>;U5::Ljava/util/List<-Ljava/lang/Number;>;U6:Ljava/lang/Number;:Ljava/lang/Runnable;:Ljava/lang/Cloneable;>Ljava/lang/Object;Ljava/util/Comparator<Ljava/lang/Integer;>;
+// declaration: jdk5/AllStructures<U0, U1 extends java.lang.Number, U2 extends java.util.List<java.lang.String>, U3 extends java.util.List<?>, U4 extends java.util.List<? extends java.lang.Number>, U5 extends java.util.List<? super java.lang.Number>, U6 extends java.lang.Number extends java.lang.Runnable, java.lang.Cloneable> implements java.util.Comparator<java.lang.Integer>
+class jdk5/AllStructures implements java/util/Comparator {
+
+ // compiled from: AllStructures.java
+
+ @Ljava/lang/Deprecated;()
+
+ @Ljdk5/AllStructures$InvisibleAnnotation;(byteValue=(byte)0, charValue=(char)0, booleanValue=false, intValue=0, shortValue=(short)0, longValue=0L, floatValue=0.0F, doubleValue=0.0D, stringValue="0", classValue=jdk5.AllStructures.class, enumValue=Ljdk5/AllStructures$EnumClass;.VALUE0, annotationValue=@Ljava/lang/Deprecated;(), byteArrayValue={(byte)0}, charArrayValue={(char)48}, booleanArrayValue={false}, intArrayValue={0}, shortArrayValue={(short)0}, longArrayValue={0L}, floatArrayValue={0.0F}, doubleArrayValue={0.0D}, stringArrayValue={"0"}, classArrayValue={jdk5.AllStructures.class, int.class, int[].class}, enumArrayValue={Ljdk5/AllStructures$EnumClass;.VALUE0}, annotationArrayValue={@Ljava/lang/Deprecated;()}, otherArrayValue={}) // invisible
+ // access flags 0x0
+ INNERCLASS jdk5/AllStructures$GenericInnerClass jdk5/AllStructures GenericInnerClass
+ // access flags 0x0
+ INNERCLASS jdk5/AllStructures$InnerClass jdk5/AllStructures InnerClass
+ // access flags 0x4018
+ final static enum INNERCLASS jdk5/AllStructures$EnumClass jdk5/AllStructures EnumClass
+ // access flags 0x2608
+ static abstract INNERCLASS jdk5/AllStructures$InvisibleAnnotation jdk5/AllStructures InvisibleAnnotation
+ // access flags 0x0
+ INNERCLASS jdk5/AllStructures$1LocalClass null LocalClass
+
+ // DEPRECATED
+ // access flags 0x20001
+ public I f
+ @Ljava/lang/Deprecated;()
+ @Ljdk5/AllStructures$InvisibleAnnotation;(otherArrayValue={2}) // invisible
+
+ // access flags 0x2
+ // signature TU0;
+ // declaration: f0 extends U0
+ private Ljava/lang/Object; f0
+
+ // access flags 0x2
+ // signature TU1;
+ // declaration: f1 extends U1
+ private Ljava/lang/Number; f1
+
+ // access flags 0x2
+ // signature TU2;
+ // declaration: f2 extends U2
+ private Ljava/util/List; f2
+
+ // access flags 0x2
+ // signature TU3;
+ // declaration: f3 extends U3
+ private Ljava/util/List; f3
+
+ // access flags 0x2
+ // signature TU4;
+ // declaration: f4 extends U4
+ private Ljava/util/List; f4
+
+ // access flags 0x2
+ // signature TU5;
+ // declaration: f5 extends U5
+ private Ljava/util/List; f5
+
+ // access flags 0x2
+ // signature TU6;
+ // declaration: f6 extends U6
+ private Ljava/lang/Number; f6
+
+ // access flags 0x0
+ <init>()V
+ L0
+ LINENUMBER 69 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ L1
+ LINENUMBER 225 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L2 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // DEPRECATED
+ // access flags 0x20001
+ public m()I
+ @Ljava/lang/Deprecated;()
+ @Ljdk5/AllStructures$InvisibleAnnotation;(otherArrayValue={3}) // invisible
+ L0
+ LINENUMBER 94 L0
+ ALOAD 0
+ GETFIELD jdk5/AllStructures.f : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L1 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public n(IFFJD)I
+ // annotable parameter count: 5 (visible)
+ @Ljava/lang/Deprecated;() // parameter 1
+ @Ljava/lang/Deprecated;() // parameter 2
+ // annotable parameter count: 5 (invisible)
+ @Ljdk5/AllStructures$InvisibleAnnotation;(otherArrayValue={4}) // invisible, parameter 1
+ @Ljdk5/AllStructures$InvisibleAnnotation;(otherArrayValue={5}) // invisible, parameter 4
+ L0
+ LINENUMBER 103 L0
+ ALOAD 0
+ GETFIELD jdk5/AllStructures.f : I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L1 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE p0 I L0 L1 1
+ LOCALVARIABLE p1 F L0 L1 2
+ LOCALVARIABLE p2 F L0 L1 3
+ LOCALVARIABLE p3 J L0 L1 4
+ LOCALVARIABLE p4 D L0 L1 6
+ MAXSTACK = 1
+ MAXLOCALS = 8
+
+ // access flags 0x1
+ // signature ()TU0;
+ // declaration: U0 o()
+ public o()Ljava/lang/Object;
+ L0
+ LINENUMBER 107 L0
+ ALOAD 0
+ GETFIELD jdk5/AllStructures.f0 : Ljava/lang/Object;
+ ARETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L1 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x0
+ // signature <U0:Ljava/lang/Object;U1:Ljava/lang/Number;U2::Ljava/util/List<Ljava/lang/String;>;U3::Ljava/util/List<*>;U4::Ljava/util/List<+Ljava/lang/Number;>;U5::Ljava/util/List<-Ljava/lang/Number;>;U6:Ljava/lang/Number;:Ljava/lang/Runnable;:Ljava/lang/Cloneable;U7:Ljava/lang/Exception;U8:Ljava/io/IOException;>(Ljava/util/List<TU0;>;Ljava/util/List<[TU1;>;Ljava/util/List<[[TU2;>;Ljava/util/List<TU3;>;Ljava/util/List<TU4;>;Ljava/util/List<TU5;>;Ljava/util/List<TU6;>;Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>.InnerClass;Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>.GenericInnerClass<TU1;>;)V^TU7;^TU8;
+ // declaration: void genericMethod<U0, U1 extends java.lang.Number, U2 extends java.util.List<java.lang.String>, U3 extends java.util.List<?>, U4 extends java.util.List<? extends java.lang.Number>, U5 extends java.util.List<? super java.lang.Number>, U6 extends java.lang.Number extends java.lang.Runnable, java.lang.Cloneable, U7 extends java.lang.Exception, U8 extends java.io.IOException>(java.util.List<U0>, java.util.List<U1[]>, java.util.List<U2[][]>, java.util.List<U3>, java.util.List<U4>, java.util.List<U5>, java.util.List<U6>, jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>.InnerClass, jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>.GenericInnerClass<U1>) throws U7, U8
+ genericMethod(Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljdk5/AllStructures$InnerClass;Ljdk5/AllStructures$GenericInnerClass;)V throws java/lang/Exception java/io/IOException
+ L0
+ LINENUMBER 130 L0
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L1 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE p0 Ljava/util/List; L0 L1 1
+ // signature Ljava/util/List<TU0;>;
+ // declaration: p0 extends java.util.List<U0>
+ LOCALVARIABLE p1 Ljava/util/List; L0 L1 2
+ // signature Ljava/util/List<[TU1;>;
+ // declaration: p1 extends java.util.List<U1[]>
+ LOCALVARIABLE p2 Ljava/util/List; L0 L1 3
+ // signature Ljava/util/List<[[TU2;>;
+ // declaration: p2 extends java.util.List<U2[][]>
+ LOCALVARIABLE p3 Ljava/util/List; L0 L1 4
+ // signature Ljava/util/List<TU3;>;
+ // declaration: p3 extends java.util.List<U3>
+ LOCALVARIABLE p4 Ljava/util/List; L0 L1 5
+ // signature Ljava/util/List<TU4;>;
+ // declaration: p4 extends java.util.List<U4>
+ LOCALVARIABLE p5 Ljava/util/List; L0 L1 6
+ // signature Ljava/util/List<TU5;>;
+ // declaration: p5 extends java.util.List<U5>
+ LOCALVARIABLE p6 Ljava/util/List; L0 L1 7
+ // signature Ljava/util/List<TU6;>;
+ // declaration: p6 extends java.util.List<U6>
+ LOCALVARIABLE p7 Ljdk5/AllStructures$InnerClass; L0 L1 8
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>.InnerClass;
+ // declaration: p7 extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>.InnerClass
+ LOCALVARIABLE p8 Ljdk5/AllStructures$GenericInnerClass; L0 L1 9
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>.GenericInnerClass<TU1;>;
+ // declaration: p8 extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>.GenericInnerClass<U1>
+ MAXSTACK = 0
+ MAXLOCALS = 10
+
+ // access flags 0x80
+ varargs varArgsAutoBoxingAndForLoop([I)I
+ L0
+ LINENUMBER 133 L0
+ ICONST_0
+ ISTORE 2
+ L1
+ LINENUMBER 134 L1
+ ALOAD 1
+ ASTORE 3
+ L2
+ ALOAD 3
+ ARRAYLENGTH
+ ISTORE 4
+ L3
+ ICONST_0
+ ISTORE 5
+ L4
+ ILOAD 5
+ ILOAD 4
+ IF_ICMPGE L5
+ ALOAD 3
+ ILOAD 5
+ IALOAD
+ ISTORE 6
+ L6
+ LINENUMBER 135 L6
+ ILOAD 2
+ ILOAD 6
+ IADD
+ ISTORE 2
+ L7
+ LINENUMBER 134 L7
+ IINC 5 1
+ GOTO L4
+ L5
+ LINENUMBER 137 L5
+ ILOAD 2
+ IRETURN
+ L8
+ LOCALVARIABLE arg I L6 L7 6
+ LOCALVARIABLE arr$ [I L2 L5 3
+ LOCALVARIABLE len$ I L3 L5 4
+ LOCALVARIABLE i$ I L4 L5 5
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L8 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE args [I L0 L8 1
+ LOCALVARIABLE total I L1 L8 2
+ MAXSTACK = 2
+ MAXLOCALS = 7
+
+ // access flags 0x0
+ localClassConstructor(Ljava/lang/String;)V
+ L0
+ LINENUMBER 146 L0
+ NEW jdk5/AllStructures$1LocalClass
+ DUP
+ ALOAD 0
+ BIPUSH 42
+ ALOAD 1
+ INVOKESPECIAL jdk5/AllStructures$1LocalClass.<init> (Ljdk5/AllStructures;ILjava/lang/String;)V
+ POP
+ L1
+ LINENUMBER 147 L1
+ RETURN
+ L2
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L2 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE name Ljava/lang/String; L0 L2 1
+ MAXSTACK = 5
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public compare(Ljava/lang/Integer;Ljava/lang/Integer;)I
+ L0
+ LINENUMBER 151 L0
+ ALOAD 1
+ INVOKEVIRTUAL java/lang/Integer.intValue ()I
+ ALOAD 2
+ INVOKEVIRTUAL java/lang/Integer.intValue ()I
+ IF_ICMPGE L1
+ ICONST_M1
+ GOTO L2
+ L1
+ ICONST_1
+ L2
+ IRETURN
+ L3
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L3 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE a Ljava/lang/Integer; L0 L3 1
+ LOCALVARIABLE b Ljava/lang/Integer; L0 L3 2
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x1041
+ public synthetic bridge compare(Ljava/lang/Object;Ljava/lang/Object;)I
+ L0
+ LINENUMBER 69 L0
+ ALOAD 0
+ ALOAD 1
+ CHECKCAST java/lang/Integer
+ ALOAD 2
+ CHECKCAST java/lang/Integer
+ INVOKEVIRTUAL jdk5/AllStructures.compare (Ljava/lang/Integer;Ljava/lang/Integer;)I
+ IRETURN
+ L1
+ LOCALVARIABLE this Ljdk5/AllStructures; L0 L1 0
+ // signature Ljdk5/AllStructures<TU0;TU1;TU2;TU3;TU4;TU5;TU6;>;
+ // declaration: this extends jdk5.AllStructures<U0, U1, U2, U3, U4, U5, U6>
+ LOCALVARIABLE x0 Ljava/lang/Object; L0 L1 1
+ LOCALVARIABLE x1 Ljava/lang/Object; L0 L1 2
+ MAXSTACK = 3
+ MAXLOCALS = 3
+}
diff --git a/asm-util/src/test/resources/jdk8.AllFrames.txt b/asm-util/src/test/resources/jdk8.AllFrames.txt
new file mode 100644
index 00000000..8dea110f
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.AllFrames.txt
@@ -0,0 +1,951 @@
+// class version 52.0 (52)
+// access flags 0x21
+public class jdk8/AllFrames {
+
+ // compiled from: AllFrames.java
+
+ // access flags 0x0
+ Ljava/lang/Object; o
+
+ // access flags 0x0
+ Ljava/lang/String; s
+
+ // access flags 0x0
+ I f
+
+ // access flags 0x1
+ public <init>(Ljava/lang/Object;Ljava/lang/String;)V
+ // parameter o
+ // parameter s
+ L0
+ LINENUMBER 42 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ L1
+ LINENUMBER 43 L1
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk8/AllFrames.o : Ljava/lang/Object;
+ L2
+ LINENUMBER 44 L2
+ ALOAD 0
+ ALOAD 2
+ PUTFIELD jdk8/AllFrames.s : Ljava/lang/String;
+ L3
+ LINENUMBER 45 L3
+ RETURN
+ L4
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L4 0
+ LOCALVARIABLE o Ljava/lang/Object; L0 L4 1
+ LOCALVARIABLE s Ljava/lang/String; L0 L4 2
+ MAXSTACK = 2
+ MAXLOCALS = 3
+
+ // access flags 0x1
+ public <init>(Z)V
+ // parameter b
+ L0
+ LINENUMBER 50 L0
+ ALOAD 0
+ ACONST_NULL
+ ILOAD 1
+ IFEQ L1
+ LDC "true"
+ GOTO L2
+ L1
+ FRAME FULL [U I] [U N]
+ LDC "false"
+ L2
+ FRAME FULL [U I] [U N java/lang/String]
+ INVOKESPECIAL jdk8/AllFrames.<init> (Ljava/lang/Object;Ljava/lang/String;)V
+ L3
+ LINENUMBER 51 L3
+ RETURN
+ L4
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L4 0
+ LOCALVARIABLE b Z L0 L4 1
+ MAXSTACK = 3
+ MAXLOCALS = 2
+
+ // access flags 0x9
+ public static create(Ljava/lang/String;)Ljdk8/AllFrames;
+ // parameter s
+ L0
+ LINENUMBER 56 L0
+ NEW jdk8/AllFrames
+ DUP
+ ACONST_NULL
+ ALOAD 0
+ IFNONNULL L1
+ LDC ""
+ GOTO L2
+ L1
+ FRAME FULL [java/lang/String] [L0 L0 N]
+ ALOAD 0
+ L2
+ FRAME FULL [java/lang/String] [L0 L0 N java/lang/String]
+ INVOKESPECIAL jdk8/AllFrames.<init> (Ljava/lang/Object;Ljava/lang/String;)V
+ ARETURN
+ L3
+ LOCALVARIABLE s Ljava/lang/String; L0 L3 0
+ MAXSTACK = 4
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public m0(ZBCSIFJDLjava/lang/Object;[Ljava/lang/Object;[[Ljava/lang/Object;)I
+ // parameter b
+ // parameter y
+ // parameter c
+ // parameter s
+ // parameter i
+ // parameter f
+ // parameter l
+ // parameter d
+ // parameter o
+ // parameter p
+ // parameter q
+ L0
+ LINENUMBER 73 L0
+ ILOAD 1
+ IFEQ L1
+ ALOAD 0
+ ILOAD 1
+ IFNE L2
+ ICONST_1
+ GOTO L3
+ L2
+ FRAME SAME1 jdk8/AllFrames
+ ICONST_0
+ L3
+ FRAME FULL [jdk8/AllFrames I I I I I F J D java/lang/Object [Ljava/lang/Object; [[Ljava/lang/Object;] [jdk8/AllFrames I]
+ ILOAD 2
+ ILOAD 3
+ ILOAD 4
+ ILOAD 5
+ ICONST_1
+ ISUB
+ FLOAD 6
+ FCONST_1
+ FSUB
+ LLOAD 7
+ LCONST_1
+ LSUB
+ DLOAD 9
+ DCONST_1
+ DSUB
+ ALOAD 11
+ ALOAD 12
+ ALOAD 13
+ L4
+ LINENUMBER 74 L4
+ INVOKEVIRTUAL jdk8/AllFrames.m0 (ZBCSIFJDLjava/lang/Object;[Ljava/lang/Object;[[Ljava/lang/Object;)I
+ GOTO L5
+ L1
+ FRAME SAME
+ ALOAD 0
+ ILOAD 1
+ IFNE L6
+ ICONST_1
+ GOTO L7
+ L6
+ FRAME SAME1 jdk8/AllFrames
+ ICONST_0
+ L7
+ FRAME FULL [jdk8/AllFrames I I I I I F J D java/lang/Object [Ljava/lang/Object; [[Ljava/lang/Object;] [jdk8/AllFrames I]
+ ILOAD 2
+ ILOAD 3
+ ILOAD 4
+ ILOAD 5
+ ICONST_1
+ IADD
+ FLOAD 6
+ FCONST_1
+ FADD
+ LLOAD 7
+ LCONST_1
+ LADD
+ DLOAD 9
+ DCONST_1
+ DADD
+ ALOAD 11
+ ALOAD 12
+ ALOAD 13
+ L8
+ LINENUMBER 75 L8
+ INVOKEVIRTUAL jdk8/AllFrames.m0 (ZBCSIFJDLjava/lang/Object;[Ljava/lang/Object;[[Ljava/lang/Object;)I
+ L5
+ LINENUMBER 73 L5
+ FRAME SAME1 I
+ IRETURN
+ L9
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L9 0
+ LOCALVARIABLE b Z L0 L9 1
+ LOCALVARIABLE y B L0 L9 2
+ LOCALVARIABLE c C L0 L9 3
+ LOCALVARIABLE s S L0 L9 4
+ LOCALVARIABLE i I L0 L9 5
+ LOCALVARIABLE f F L0 L9 6
+ LOCALVARIABLE l J L0 L9 7
+ LOCALVARIABLE d D L0 L9 9
+ LOCALVARIABLE o Ljava/lang/Object; L0 L9 11
+ LOCALVARIABLE p [Ljava/lang/Object; L0 L9 12
+ LOCALVARIABLE q [[Ljava/lang/Object; L0 L9 13
+ MAXSTACK = 14
+ MAXLOCALS = 14
+
+ // access flags 0x1
+ public m0([BZ)Ljava/lang/String;
+ // parameter bytes
+ // parameter b
+ TRYCATCHBLOCK L0 L1 L2 java/io/UnsupportedEncodingException
+ L0
+ LINENUMBER 81 L0
+ ALOAD 1
+ IFNONNULL L3
+ ACONST_NULL
+ GOTO L1
+ L3
+ FRAME SAME
+ NEW java/lang/String
+ DUP
+ ALOAD 1
+ ILOAD 2
+ IFEQ L4
+ LDC "a"
+ GOTO L5
+ L4
+ FRAME FULL [jdk8/AllFrames [B I] [L3 L3 [B]
+ LDC "b"
+ L5
+ FRAME FULL [jdk8/AllFrames [B I] [L3 L3 [B java/lang/String]
+ INVOKESPECIAL java/lang/String.<init> ([BLjava/lang/String;)V
+ L1
+ FRAME SAME1 java/lang/String
+ ARETURN
+ L2
+ LINENUMBER 82 L2
+ FRAME SAME1 java/io/UnsupportedEncodingException
+ ASTORE 3
+ L6
+ LINENUMBER 83 L6
+ ACONST_NULL
+ ARETURN
+ L7
+ LOCALVARIABLE e Ljava/io/UnsupportedEncodingException; L6 L7 3
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L7 0
+ LOCALVARIABLE bytes [B L0 L7 1
+ LOCALVARIABLE b Z L0 L7 2
+ MAXSTACK = 4
+ MAXLOCALS = 4
+
+ // access flags 0x1
+ public m1(II)V
+ // parameter i
+ // parameter j
+ L0
+ LINENUMBER 91 L0
+ ILOAD 2
+ ISTORE 4
+ L1
+ LINENUMBER 92 L1
+ ILOAD 1
+ IFGE L2
+ L3
+ LINENUMBER 93 L3
+ ILOAD 1
+ INEG
+ ISTORE 1
+ L2
+ LINENUMBER 95 L2
+ FRAME APPEND [T I]
+ RETURN
+ L4
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L4 0
+ LOCALVARIABLE i I L0 L4 1
+ LOCALVARIABLE j I L0 L4 2
+ LOCALVARIABLE l I L1 L4 4
+ MAXSTACK = 1
+ MAXLOCALS = 5
+
+ // access flags 0x1
+ public m2(IZ)J
+ // parameter n
+ // parameter b
+ L0
+ LINENUMBER 99 L0
+ LCONST_0
+ LSTORE 3
+ L1
+ LINENUMBER 100 L1
+ ILOAD 2
+ IFEQ L2
+ L3
+ LINENUMBER 101 L3
+ ICONST_0
+ ISTORE 5
+ L4
+ LINENUMBER 103 L4
+ FRAME APPEND [J I]
+ LLOAD 3
+ ILOAD 5
+ IINC 5 1
+ I2L
+ LADD
+ LSTORE 3
+ L5
+ LINENUMBER 104 L5
+ ILOAD 5
+ ILOAD 1
+ IF_ICMPLT L4
+ L6
+ LINENUMBER 105 L6
+ GOTO L7
+ L2
+ LINENUMBER 106 L2
+ FRAME CHOP 1
+ LCONST_0
+ LSTORE 5
+ L8
+ LINENUMBER 108 L8
+ FRAME APPEND [J]
+ LLOAD 3
+ LLOAD 5
+ DUP2
+ LCONST_1
+ LADD
+ LSTORE 5
+ LADD
+ LSTORE 3
+ L9
+ LINENUMBER 109 L9
+ LLOAD 5
+ ILOAD 1
+ I2L
+ LCMP
+ IFLT L8
+ L7
+ LINENUMBER 111 L7
+ FRAME CHOP 1
+ LLOAD 3
+ LRETURN
+ L10
+ LOCALVARIABLE i I L4 L6 5
+ LOCALVARIABLE i J L8 L7 5
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L10 0
+ LOCALVARIABLE n I L0 L10 1
+ LOCALVARIABLE b Z L0 L10 2
+ LOCALVARIABLE total J L1 L10 3
+ MAXSTACK = 8
+ MAXLOCALS = 7
+
+ // access flags 0x1
+ public m3(I)I
+ // parameter i
+ L0
+ LINENUMBER 116 L0
+ ILOAD 1
+ IFGE L1
+ L2
+ LINENUMBER 117 L2
+ ILOAD 1
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ISTORE 1
+ L3
+ LINENUMBER 118 L3
+ ILOAD 1
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ISTORE 1
+ L1
+ LINENUMBER 120 L1
+ FRAME SAME
+ ILOAD 1
+ IRETURN
+ L4
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L4 0
+ LOCALVARIABLE i I L0 L4 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public m4(I)V
+ // parameter i
+ L0
+ LINENUMBER 125 L0
+ ILOAD 1
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ISTORE 1
+ L1
+ LINENUMBER 126 L1
+ ILOAD 1
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ILOAD 1
+ IADD
+ ISTORE 1
+ L2
+ LINENUMBER 127 L2
+ ALOAD 0
+ ILOAD 1
+ IFNE L3
+ LDC "true"
+ GOTO L4
+ L3
+ FRAME SAME1 jdk8/AllFrames
+ LDC "false"
+ L4
+ FRAME FULL [jdk8/AllFrames I] [jdk8/AllFrames java/lang/String]
+ PUTFIELD jdk8/AllFrames.s : Ljava/lang/String;
+ L5
+ LINENUMBER 128 L5
+ RETURN
+ L6
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L6 0
+ LOCALVARIABLE i I L0 L6 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x9
+ public static m5(Z)Ljava/lang/Number;
+ // parameter b
+ L0
+ LINENUMBER 132 L0
+ ILOAD 0
+ IFEQ L1
+ NEW java/lang/Integer
+ DUP
+ ICONST_1
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ INVOKEVIRTUAL java/lang/Integer.intValue ()I
+ I2F
+ GOTO L2
+ L1
+ FRAME SAME
+ NEW java/lang/Float
+ DUP
+ FCONST_1
+ INVOKESPECIAL java/lang/Float.<init> (F)V
+ INVOKEVIRTUAL java/lang/Float.floatValue ()F
+ L2
+ FRAME SAME1 F
+ INVOKESTATIC java/lang/Float.valueOf (F)Ljava/lang/Float;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m6(Z)[Ljava/lang/Number;
+ // parameter b
+ L0
+ LINENUMBER 137 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ANEWARRAY java/lang/Integer
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ANEWARRAY java/lang/Float
+ L2
+ FRAME SAME1 [Ljava/lang/Number;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m7(Z)[[Ljava/lang/Number;
+ // parameter b
+ L0
+ LINENUMBER 142 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[Ljava/lang/Integer; 2
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[Ljava/lang/Float; 2
+ L2
+ FRAME SAME1 [[Ljava/lang/Number;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m8(Z)[Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 147 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[B 2
+ CHECKCAST [Ljava/lang/Object;
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[S 2
+ CHECKCAST [Ljava/lang/Object;
+ L2
+ FRAME SAME1 [Ljava/lang/Object;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m9(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 152 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ NEWARRAY T_BYTE
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ANEWARRAY java/lang/Float
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m10(Z)[Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 157 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[B 2
+ CHECKCAST [Ljava/lang/Object;
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ANEWARRAY [Ljava/lang/Float;
+ CHECKCAST [Ljava/lang/Object;
+ L2
+ FRAME SAME1 [Ljava/lang/Object;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m11(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 162 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ NEWARRAY T_BYTE
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[B 2
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m12(Z)[Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 167 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ANEWARRAY java/lang/Object
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[B 2
+ L2
+ FRAME SAME1 [Ljava/lang/Object;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m13(Z)[Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 172 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[B 2
+ CHECKCAST [Ljava/lang/Object;
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[[B 3
+ CHECKCAST [Ljava/lang/Object;
+ L2
+ FRAME SAME1 [Ljava/lang/Object;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m14(Z)[[Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 177 L0
+ ILOAD 0
+ IFEQ L1
+ ICONST_1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[[B 3
+ CHECKCAST [[Ljava/lang/Object;
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ICONST_1
+ ICONST_1
+ ICONST_1
+ MULTIANEWARRAY [[[[B 4
+ CHECKCAST [[Ljava/lang/Object;
+ L2
+ FRAME SAME1 [[Ljava/lang/Object;
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 4
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m15(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 182 L0
+ ILOAD 0
+ IFEQ L1
+ NEW java/lang/Integer
+ DUP
+ ICONST_1
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ NEWARRAY T_CHAR
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m16(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 187 L0
+ ILOAD 0
+ IFEQ L1
+ NEW java/lang/Integer
+ DUP
+ ICONST_1
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_1
+ ANEWARRAY java/lang/Float
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ public m17(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 192 L0
+ ILOAD 1
+ IFEQ L1
+ ICONST_0
+ NEWARRAY T_INT
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_0
+ NEWARRAY T_BOOLEAN
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L3 0
+ LOCALVARIABLE b Z L0 L3 1
+ MAXSTACK = 1
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public m18(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 197 L0
+ ILOAD 1
+ IFEQ L1
+ ICONST_0
+ NEWARRAY T_SHORT
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_0
+ NEWARRAY T_FLOAT
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L3 0
+ LOCALVARIABLE b Z L0 L3 1
+ MAXSTACK = 1
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public m19(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 202 L0
+ ILOAD 1
+ IFEQ L1
+ ICONST_0
+ NEWARRAY T_DOUBLE
+ GOTO L2
+ L1
+ FRAME SAME
+ ICONST_0
+ NEWARRAY T_LONG
+ L2
+ FRAME SAME1 java/lang/Object
+ ARETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllFrames; L0 L3 0
+ LOCALVARIABLE b Z L0 L3 1
+ MAXSTACK = 1
+ MAXLOCALS = 2
+
+ // access flags 0x9
+ public static m20(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 207 L0
+ ILOAD 0
+ IFEQ L1
+ ACONST_NULL
+ GOTO L2
+ L1
+ FRAME SAME
+ NEW java/lang/Integer
+ DUP
+ ICONST_1
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ L2
+ FRAME SAME1 java/lang/Integer
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m21(Z)Ljava/lang/Object;
+ // parameter b
+ L0
+ LINENUMBER 212 L0
+ ILOAD 0
+ IFEQ L1
+ NEW java/lang/Integer
+ DUP
+ ICONST_1
+ INVOKESPECIAL java/lang/Integer.<init> (I)V
+ GOTO L2
+ L1
+ FRAME SAME
+ ACONST_NULL
+ L2
+ FRAME SAME1 java/lang/Integer
+ ARETURN
+ L3
+ LOCALVARIABLE b Z L0 L3 0
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static m23()I
+ L0
+ LINENUMBER 218 L0
+ ACONST_NULL
+ ASTORE 0
+ L1
+ LINENUMBER 219 L1
+ ALOAD 0
+ ICONST_0
+ AALOAD
+ INVOKEVIRTUAL java/lang/Integer.intValue ()I
+ IRETURN
+ L2
+ LOCALVARIABLE array [Ljava/lang/Integer; L1 L2 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk8.AllInstructions.txt b/asm-util/src/test/resources/jdk8.AllInstructions.txt
new file mode 100644
index 00000000..583329d8
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.AllInstructions.txt
@@ -0,0 +1,103 @@
+// class version 52.0 (52)
+// access flags 0x20
+class jdk8/AllInstructions {
+
+ // compiled from: AllInstructions.java
+ // access flags 0x19
+ public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
+
+ // access flags 0x0
+ <init>()V
+ L0
+ LINENUMBER 10 L0
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllInstructions; L0 L1 0
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ // signature (Ljava/util/List<Ljava/lang/String;>;)V
+ // declaration: void invokedynamic(java.util.List<java.lang.String>)
+ public invokedynamic(Ljava/util/List;)V
+ // parameter strings
+ L0
+ LINENUMBER 12 L0
+ ICONST_3
+ ANEWARRAY java/lang/String
+ DUP
+ ICONST_0
+ LDC "a"
+ AASTORE
+ DUP
+ ICONST_1
+ LDC "b"
+ AASTORE
+ DUP
+ ICONST_2
+ LDC "c"
+ AASTORE
+ INVOKESTATIC java/util/Arrays.asList ([Ljava/lang/Object;)Ljava/util/List;
+ ASTORE 2
+ L1
+ LINENUMBER 13 L1
+ ALOAD 1
+ ALOAD 2
+ INVOKEDYNAMIC accept(Ljava/util/List;)Ljava/util/function/Consumer; [
+ // handle kind 0x6 : INVOKESTATIC
+ java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ // arguments:
+ (Ljava/lang/Object;)V,
+ // handle kind 0x6 : INVOKESTATIC
+ jdk8/AllInstructions.lambda$invokedynamic$0(Ljava/util/List;Ljava/lang/String;)V,
+ (Ljava/lang/String;)V
+ ]
+ INVOKEINTERFACE java/util/List.forEach (Ljava/util/function/Consumer;)V (itf)
+ L2
+ LINENUMBER 17 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllInstructions; L0 L3 0
+ LOCALVARIABLE strings Ljava/util/List; L0 L3 1
+ // signature Ljava/util/List<Ljava/lang/String;>;
+ // declaration: strings extends java.util.List<java.lang.String>
+ LOCALVARIABLE validStrings Ljava/util/List; L1 L3 2
+ // signature Ljava/util/List<Ljava/lang/String;>;
+ // declaration: validStrings extends java.util.List<java.lang.String>
+ MAXSTACK = 4
+ MAXLOCALS = 3
+
+ // access flags 0x100A
+ private static synthetic lambda$invokedynamic$0(Ljava/util/List;Ljava/lang/String;)V
+ // parameter final synthetic validStrings
+ // parameter synthetic s
+ L0
+ LINENUMBER 14 L0
+ ALOAD 0
+ ALOAD 1
+ INVOKEINTERFACE java/util/List.contains (Ljava/lang/Object;)Z (itf)
+ IFNE L1
+ L2
+ LINENUMBER 15 L2
+ GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
+ LDC "Invalid string %s\n"
+ ICONST_1
+ ANEWARRAY java/lang/Object
+ DUP
+ ICONST_0
+ ALOAD 1
+ AASTORE
+ INVOKEVIRTUAL java/io/PrintStream.printf (Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
+ POP
+ L1
+ LINENUMBER 16 L1
+ FRAME SAME
+ RETURN
+ L3
+ LOCALVARIABLE validStrings Ljava/util/List; L0 L3 0
+ LOCALVARIABLE s Ljava/lang/String; L0 L3 1
+ MAXSTACK = 6
+ MAXLOCALS = 2
+}
diff --git a/asm-util/src/test/resources/jdk8.AllStructures$1.txt b/asm-util/src/test/resources/jdk8.AllStructures$1.txt
new file mode 100644
index 00000000..82ce5763
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.AllStructures$1.txt
@@ -0,0 +1,75 @@
+// class version 52.0 (52)
+// access flags 0x20
+class jdk8/AllStructures$1 implements java/lang/Runnable {
+
+ // compiled from: AllStructures.java
+ OUTERCLASS jdk8/AllStructures anonymousInnerClass ()Ljava/lang/Runnable;
+ // access flags 0x0
+ INNERCLASS jdk8/AllStructures$1 null null
+ // access flags 0x2
+ private INNERCLASS jdk8/AllStructures$InnerClass jdk8/AllStructures InnerClass
+
+ // access flags 0x1010
+ final synthetic Ljdk8/AllStructures; this$0
+
+ // access flags 0x0
+ <init>(Ljdk8/AllStructures;)V
+ // parameter final mandated this$0
+ L0
+ LINENUMBER 99 L0
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk8/AllStructures$1.this$0 : Ljdk8/AllStructures;
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllStructures$1; L0 L1 0
+ // signature Ljdk8/AllStructures$1;
+ // declaration: this extends jdk8.AllStructures$1
+ LOCALVARIABLE this$0 Ljdk8/AllStructures; L0 L1 1
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public run()V
+ L0
+ LINENUMBER 103 L0
+ NEW jdk8/AllStructures$InnerClass
+ DUP
+ ALOAD 0
+ GETFIELD jdk8/AllStructures$1.this$0 : Ljdk8/AllStructures;
+ ALOAD 0
+ GETFIELD jdk8/AllStructures$1.this$0 : Ljdk8/AllStructures;
+ INVOKESTATIC jdk8/AllStructures.access$000 (Ljdk8/AllStructures;)D
+ ALOAD 0
+ GETFIELD jdk8/AllStructures$1.this$0 : Ljdk8/AllStructures;
+ INVOKESTATIC jdk8/AllStructures.access$100 (Ljdk8/AllStructures;)D
+ DADD
+ ACONST_NULL
+ INVOKESPECIAL jdk8/AllStructures$InnerClass.<init> (Ljdk8/AllStructures;DLjdk8/AllStructures$1;)V
+ INVOKESTATIC jdk8/AllStructures$InnerClass.access$300 (Ljdk8/AllStructures$InnerClass;)D
+ DSTORE 1
+ L1
+ LINENUMBER 104 L1
+ NEW jdk8/AllStructures$InnerClass
+ DUP
+ ALOAD 0
+ GETFIELD jdk8/AllStructures$1.this$0 : Ljdk8/AllStructures;
+ DLOAD 1
+ ACONST_NULL
+ INVOKESPECIAL jdk8/AllStructures$InnerClass.<init> (Ljdk8/AllStructures;DLjdk8/AllStructures$1;)V
+ POP
+ L2
+ LINENUMBER 105 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllStructures$1; L0 L3 0
+ // signature Ljdk8/AllStructures$1;
+ // declaration: this extends jdk8.AllStructures$1
+ LOCALVARIABLE f D L1 L3 1
+ LOCALVARIABLE @Lannotations/VTUA;(v=0) : LOCAL_VARIABLE, null [ L1 - L3 - 1 ]
+ LOCALVARIABLE @Lannotations/ITUA;(v=1) : LOCAL_VARIABLE, null [ L1 - L3 - 1 ] // invisible
+ MAXSTACK = 7
+ MAXLOCALS = 3
+}
diff --git a/asm-util/src/test/resources/jdk8.AllStructures$InnerClass.txt b/asm-util/src/test/resources/jdk8.AllStructures$InnerClass.txt
new file mode 100644
index 00000000..af5fe9a7
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.AllStructures$InnerClass.txt
@@ -0,0 +1,76 @@
+// class version 52.0 (52)
+// access flags 0x20
+class jdk8/AllStructures$InnerClass {
+
+ // compiled from: AllStructures.java
+ // access flags 0x2
+ private INNERCLASS jdk8/AllStructures$InnerClass jdk8/AllStructures InnerClass
+ // access flags 0x0
+ INNERCLASS jdk8/AllStructures$1 null null
+
+ // access flags 0x12
+ private final D f
+ @Lannotations/VTUA;(v=0) : FIELD, null
+ @Lannotations/ITUA;(v=1) : FIELD, null // invisible
+
+ // access flags 0x1010
+ final synthetic Ljdk8/AllStructures; this$0
+
+ // access flags 0x2
+ private <init>(Ljdk8/AllStructures;D)V
+ // parameter final synthetic this$0
+ // parameter f
+ L0
+ LINENUMBER 115 L0
+ ALOAD 0
+ ALOAD 1
+ PUTFIELD jdk8/AllStructures$InnerClass.this$0 : Ljdk8/AllStructures;
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ L1
+ LINENUMBER 116 L1
+ ALOAD 0
+ DLOAD 2
+ PUTFIELD jdk8/AllStructures$InnerClass.f : D
+ L2
+ LINENUMBER 117 L2
+ RETURN
+ L3
+ LOCALVARIABLE this Ljdk8/AllStructures$InnerClass; L0 L3 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>.InnerClass;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>.InnerClass
+ LOCALVARIABLE f D L0 L3 2
+ MAXSTACK = 3
+ MAXLOCALS = 4
+
+ // access flags 0x1000
+ synthetic <init>(Ljdk8/AllStructures;DLjdk8/AllStructures$1;)V
+ L0
+ LINENUMBER 109 L0
+ ALOAD 0
+ ALOAD 1
+ DLOAD 2
+ INVOKESPECIAL jdk8/AllStructures$InnerClass.<init> (Ljdk8/AllStructures;D)V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllStructures$InnerClass; L0 L1 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>.InnerClass;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>.InnerClass
+ LOCALVARIABLE x0 Ljdk8/AllStructures; L0 L1 1
+ LOCALVARIABLE x1 D L0 L1 2
+ LOCALVARIABLE x2 Ljdk8/AllStructures$1; L0 L1 4
+ MAXSTACK = 4
+ MAXLOCALS = 5
+
+ // access flags 0x1008
+ static synthetic access$300(Ljdk8/AllStructures$InnerClass;)D
+ L0
+ LINENUMBER 109 L0
+ ALOAD 0
+ GETFIELD jdk8/AllStructures$InnerClass.f : D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk8/AllStructures$InnerClass; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk8.AllStructures.txt b/asm-util/src/test/resources/jdk8.AllStructures.txt
new file mode 100644
index 00000000..a6a11ed2
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.AllStructures.txt
@@ -0,0 +1,294 @@
+// class version 52.0 (52)
+// access flags 0x421
+// signature <U0:Ljava/lang/Object;U1::Ljava/util/List<TU0;>;U2::Ljava/util/Collection<TU0;>;>Ljava/util/HashMap<TU0;TU1;>;Ljava/util/concurrent/Callable<TU0;>;Ljava/util/concurrent/Future<TU1;>;
+// declaration: jdk8/AllStructures<U0, U1 extends java.util.List<U0>, U2 extends java.util.Collection<U0>> extends java.util.HashMap<U0, U1> implements java.util.concurrent.Callable<U0>, java.util.concurrent.Future<U1>
+public abstract class jdk8/AllStructures extends java/util/HashMap implements java/util/concurrent/Callable java/util/concurrent/Future {
+
+ // compiled from: AllStructures.java
+
+ @Lannotations/VTA;(v=0)
+
+ @Lannotations/ITA;(v=1) // invisible
+
+ @Lannotations/VTUA;(v=14) : CLASS_EXTENDS -1, null
+
+ @Lannotations/VTUA;(v=16) : CLASS_EXTENDS -1, 0;
+
+ @Lannotations/VTUA;(v=18) : CLASS_EXTENDS -1, 1;
+
+ @Lannotations/VTUA;(v=20) : CLASS_EXTENDS 0, null
+
+ @Lannotations/VTUA;(v=22) : CLASS_EXTENDS 0, 0;
+
+ @Lannotations/VTUA;(v=24) : CLASS_EXTENDS 1, null
+
+ @Lannotations/VTUA;(v=26) : CLASS_EXTENDS 1, 0;
+
+ @Lannotations/VTPA;(v=2) : CLASS_TYPE_PARAMETER 0, null
+
+ @Lannotations/VTPA;(v=4) : CLASS_TYPE_PARAMETER 1, null
+
+ @Lannotations/VTUA;(v=6) : CLASS_TYPE_PARAMETER_BOUND 1, 1, null
+
+ @Lannotations/VTPA;(v=8) : CLASS_TYPE_PARAMETER 2, null
+
+ @Lannotations/VTUA;(v=10) : CLASS_TYPE_PARAMETER_BOUND 2, 1, null
+
+ @Lannotations/VTUA;(v=12) : CLASS_TYPE_PARAMETER_BOUND 2, 1, 0;
+
+ @Lannotations/ITUA;(v=15) : CLASS_EXTENDS -1, null // invisible
+
+ @Lannotations/ITUA;(v=17) : CLASS_EXTENDS -1, 0; // invisible
+
+ @Lannotations/ITUA;(v=19) : CLASS_EXTENDS -1, 1; // invisible
+
+ @Lannotations/ITUA;(v=21) : CLASS_EXTENDS 0, null // invisible
+
+ @Lannotations/ITUA;(v=23) : CLASS_EXTENDS 0, 0; // invisible
+
+ @Lannotations/ITUA;(v=25) : CLASS_EXTENDS 1, null // invisible
+
+ @Lannotations/ITUA;(v=27) : CLASS_EXTENDS 1, 0; // invisible
+
+ @Lannotations/ITPA;(v=3) : CLASS_TYPE_PARAMETER 0, null // invisible
+
+ @Lannotations/ITPA;(v=5) : CLASS_TYPE_PARAMETER 1, null // invisible
+
+ @Lannotations/ITUA;(v=7) : CLASS_TYPE_PARAMETER_BOUND 1, 1, null // invisible
+
+ @Lannotations/ITPA;(v=9) : CLASS_TYPE_PARAMETER 2, null // invisible
+
+ @Lannotations/ITUA;(v=11) : CLASS_TYPE_PARAMETER_BOUND 2, 1, null // invisible
+
+ @Lannotations/ITUA;(v=13) : CLASS_TYPE_PARAMETER_BOUND 2, 1, 0; // invisible
+ // access flags 0x2
+ private INNERCLASS jdk8/AllStructures$𝔻 jdk8/AllStructures 𝔻
+ // access flags 0x2
+ private INNERCLASS jdk8/AllStructures$InnerClass jdk8/AllStructures InnerClass
+ // access flags 0x0
+ INNERCLASS jdk8/AllStructures$1 null null
+
+ // access flags 0x1
+ // signature Ljava/util/HashMap<TU0;TU1;>;
+ // declaration: f extends java.util.HashMap<U0, U1>
+ public Ljava/util/HashMap; f
+ @Lannotations/VFA;(v=28)
+ @Lannotations/IFA;(v=29) // invisible
+ @Lannotations/VTUA;(v=30) : FIELD, 0;
+ @Lannotations/VTUA;(v=32) : FIELD, 1;
+ @Lannotations/ITUA;(v=31) : FIELD, 0; // invisible
+ @Lannotations/ITUA;(v=33) : FIELD, 1; // invisible
+
+ // access flags 0x2
+ private D g
+
+ // access flags 0x1
+ public <init>()V
+ @Lannotations/VCA;(v=34)
+ @Lannotations/ICA;(v=35) // invisible
+ L0
+ LINENUMBER 80 L0
+ ALOAD 0
+ INVOKESPECIAL java/util/HashMap.<init> ()V
+ RETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllStructures; L0 L1 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>
+ MAXSTACK = 1
+ MAXLOCALS = 1
+
+ // access flags 0x1
+ // signature <V0:TU0;V1:TU1;>(TV0;TV1;Ljava/util/Map<+TV0;+TV1;>;)Ljava/util/Map<+TV0;+TV1;>;
+ // declaration: java.util.Map<? extends V0, ? extends V1> m<V0 extends U0, V1 extends U1>(V0, V1, java.util.Map<? extends V0, ? extends V1>)
+ public m(Ljava/lang/Object;Ljava/util/List;Ljava/util/Map;)Ljava/util/Map; throws java/lang/IllegalStateException java/lang/IllegalArgumentException
+ // parameter p0
+ // parameter p1
+ // parameter p2
+ @Lannotations/VMA;(v=36)
+ @Lannotations/IMA;(v=37) // invisible
+ @Lannotations/VTUA;(v=48) : METHOD_RETURN, 0;
+ @Lannotations/VTUA;(v=50) : METHOD_RETURN, 1;
+ @Lannotations/VTPA;(v=38) : METHOD_TYPE_PARAMETER 0, null
+ @Lannotations/VTUA;(v=40) : METHOD_TYPE_PARAMETER_BOUND 0, 0, null
+ @Lannotations/VTUA;(v=42) : METHOD_TYPE_PARAMETER 1, null
+ @Lannotations/VTUA;(v=44) : METHOD_TYPE_PARAMETER_BOUND 1, 0, null
+ @Lannotations/VTUA;(v=62) : THROWS 0, null
+ @Lannotations/VTUA;(v=64) : THROWS 1, null
+ @Lannotations/VTUA;(v=46) : METHOD_RETURN, null
+ @Lannotations/VTUA;(v=58) : METHOD_FORMAL_PARAMETER 2, 0;
+ @Lannotations/VTUA;(v=60) : METHOD_FORMAL_PARAMETER 2, 1;
+ @Lannotations/ITUA;(v=49) : METHOD_RETURN, 0; // invisible
+ @Lannotations/ITUA;(v=51) : METHOD_RETURN, 1; // invisible
+ @Lannotations/ITPA;(v=39) : METHOD_TYPE_PARAMETER 0, null // invisible
+ @Lannotations/ITUA;(v=41) : METHOD_TYPE_PARAMETER_BOUND 0, 0, null // invisible
+ @Lannotations/ITUA;(v=43) : METHOD_TYPE_PARAMETER 1, null // invisible
+ @Lannotations/ITUA;(v=45) : METHOD_TYPE_PARAMETER_BOUND 1, 0, null // invisible
+ @Lannotations/ITUA;(v=63) : THROWS 0, null // invisible
+ @Lannotations/ITUA;(v=65) : THROWS 1, null // invisible
+ @Lannotations/ITUA;(v=47) : METHOD_RETURN, null // invisible
+ @Lannotations/ITUA;(v=59) : METHOD_FORMAL_PARAMETER 2, 0; // invisible
+ @Lannotations/ITUA;(v=61) : METHOD_FORMAL_PARAMETER 2, 1; // invisible
+ // annotable parameter count: 3 (visible)
+ @Lannotations/VPA;(v=52) // parameter 0
+ @Lannotations/VPA;(v=54) // parameter 1
+ @Lannotations/VPA;(v=56) // parameter 2
+ // annotable parameter count: 3 (invisible)
+ @Lannotations/IPA;(v=53) // invisible, parameter 0
+ @Lannotations/IPA;(v=55) // invisible, parameter 1
+ @Lannotations/IPA;(v=57) // invisible, parameter 2
+ TRYCATCHBLOCK L0 L1 L2 java/lang/IllegalStateException
+ TRYCATCHBLOCK L0 L1 L2 java/lang/IllegalArgumentException
+ TRYCATCHBLOCK @Lannotations/VTUA;(v=80) : EXCEPTION_PARAMETER 1, null
+ TRYCATCHBLOCK @Lannotations/VTUA;(v=78) : EXCEPTION_PARAMETER 0, null
+ TRYCATCHBLOCK @Lannotations/ITUA;(v=81) : EXCEPTION_PARAMETER 1, null // invisible
+ TRYCATCHBLOCK @Lannotations/ITUA;(v=79) : EXCEPTION_PARAMETER 0, null // invisible
+ L3
+ LINENUMBER 100 L3
+ ALOAD 2
+ ASTORE 4
+ L4
+ LINENUMBER 103 L4
+ ALOAD 3
+ ASTORE 5
+ L5
+ LINENUMBER 106 L5
+ ALOAD 4
+ @Lannotations/VTUA;(v=76) : CAST 0, null
+ @Lannotations/ITUA;(v=77) : CAST 0, null // invisible
+ CHECKCAST java/util/ArrayList
+ ASTORE 6
+ L0
+ LINENUMBER 108 L0
+ ALOAD 0
+ ALOAD 1
+ ALOAD 2
+ ALOAD 3
+ INVOKEVIRTUAL jdk8/AllStructures.m (Ljava/lang/Object;Ljava/util/List;Ljava/util/Map;)Ljava/util/Map;
+ POP
+ L1
+ LINENUMBER 113 L1
+ GOTO L6
+ L2
+ LINENUMBER 109 L2
+ FRAME FULL [jdk8/AllStructures java/lang/Object java/util/List java/util/Map java/util/List java/util/Map java/util/ArrayList] [java/lang/RuntimeException]
+ ASTORE 7
+ L6
+ LINENUMBER 114 L6
+ FRAME SAME
+ ALOAD 5
+ @Lannotations/VTUA;(v=82) : INSTANCEOF, null
+ @Lannotations/ITUA;(v=83) : INSTANCEOF, null // invisible
+ INSTANCEOF java/util/HashMap
+ IFEQ L7
+ L8
+ LINENUMBER 115 L8
+ ALOAD 5
+ ARETURN
+ L7
+ LINENUMBER 117 L7
+ FRAME SAME
+ INVOKESTATIC jdk8/AllStructures.m ()V
+ @Lannotations/VTUA;(v=84) : METHOD_INVOCATION_TYPE_ARGUMENT 0, null
+ @Lannotations/ITUA;(v=85) : METHOD_INVOCATION_TYPE_ARGUMENT 1, null // invisible
+ L9
+ LINENUMBER 118 L9
+ NEW java/util/HashMap
+ @Lannotations/VTUA;(v=86) : NEW, null
+ @Lannotations/VTUA;(v=88) : NEW, 0;
+ @Lannotations/ITUA;(v=87) : NEW, null // invisible
+ @Lannotations/ITUA;(v=89) : NEW, 1; // invisible
+ DUP
+ INVOKESPECIAL java/util/HashMap.<init> ()V
+ ARETURN
+ L10
+ LOCALVARIABLE this Ljdk8/AllStructures; L3 L10 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>
+ LOCALVARIABLE p0 Ljava/lang/Object; L3 L10 1
+ // signature TV0;
+ // declaration: p0 extends V0
+ LOCALVARIABLE p1 Ljava/util/List; L3 L10 2
+ // signature TV1;
+ // declaration: p1 extends V1
+ LOCALVARIABLE p2 Ljava/util/Map; L3 L10 3
+ // signature Ljava/util/Map<+TV0;+TV1;>;
+ // declaration: p2 extends java.util.Map<? extends V0, ? extends V1>
+ LOCALVARIABLE l1 Ljava/util/List; L4 L10 4
+ // signature TV1;
+ // declaration: l1 extends V1
+ LOCALVARIABLE l2 Ljava/util/Map; L5 L10 5
+ // signature Ljava/util/Map<+TV0;+TV1;>;
+ // declaration: l2 extends java.util.Map<? extends V0, ? extends V1>
+ LOCALVARIABLE l3 Ljava/util/ArrayList; L0 L10 6
+ LOCALVARIABLE @Lannotations/VTUA;(v=70) : LOCAL_VARIABLE, 0; [ L5 - L10 - 5 ]
+ LOCALVARIABLE @Lannotations/VTUA;(v=72) : LOCAL_VARIABLE, 1; [ L5 - L10 - 5 ]
+ LOCALVARIABLE @Lannotations/ITUA;(v=71) : LOCAL_VARIABLE, 0; [ L5 - L10 - 5 ] // invisible
+ LOCALVARIABLE @Lannotations/ITUA;(v=73) : LOCAL_VARIABLE, 1; [ L5 - L10 - 5 ] // invisible
+ MAXSTACK = 4
+ MAXLOCALS = 8
+
+ // access flags 0xA
+ // signature <U:Ljava/lang/Object;V:Ljava/lang/Object;>()V
+ // declaration: void m<U, V>()
+ private static m()V
+ L0
+ LINENUMBER 121 L0
+ RETURN
+ MAXSTACK = 0
+ MAXLOCALS = 0
+
+ // access flags 0x2
+ private n()D
+ L0
+ LINENUMBER 126 L0
+ ALOAD 0
+ GETFIELD jdk8/AllStructures.g : D
+ DRETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllStructures; L0 L1 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x2
+ private anonymousInnerClass()Ljava/lang/Runnable; throws java/lang/Exception
+ L0
+ LINENUMBER 130 L0
+ NEW jdk8/AllStructures$1
+ DUP
+ ALOAD 0
+ INVOKESPECIAL jdk8/AllStructures$1.<init> (Ljdk8/AllStructures;)V
+ ARETURN
+ L1
+ LOCALVARIABLE this Ljdk8/AllStructures; L0 L1 0
+ // signature Ljdk8/AllStructures<TU0;TU1;TU2;>;
+ // declaration: this extends jdk8.AllStructures<U0, U1, U2>
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x1008
+ static synthetic access$000(Ljdk8/AllStructures;)D
+ L0
+ LINENUMBER 64 L0
+ ALOAD 0
+ GETFIELD jdk8/AllStructures.g : D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk8/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+
+ // access flags 0x1008
+ static synthetic access$100(Ljdk8/AllStructures;)D
+ L0
+ LINENUMBER 64 L0
+ ALOAD 0
+ INVOKESPECIAL jdk8/AllStructures.n ()D
+ DRETURN
+ L1
+ LOCALVARIABLE x0 Ljdk8/AllStructures; L0 L1 0
+ MAXSTACK = 2
+ MAXLOCALS = 1
+}
diff --git a/asm-util/src/test/resources/jdk8.Artificial$()$Structures.txt b/asm-util/src/test/resources/jdk8.Artificial$()$Structures.txt
new file mode 100644
index 00000000..3bcfda7c
--- /dev/null
+++ b/asm-util/src/test/resources/jdk8.Artificial$()$Structures.txt
@@ -0,0 +1,56 @@
+// class version 52.0 (52)
+// access flags 0x21
+public class jdk8/Artificial$()$Structures {
+
+
+ // access flags 0x1
+ public I value
+
+ // access flags 0x1
+ public <init>(I)V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ ALOAD 0
+ ILOAD 1
+ PUTFIELD jdk8/Artificial$()$Structures.value : I
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x2
+ private <init>(Ljdk8/Artificial$()$Structures;)V
+ ALOAD 0
+ INVOKESPECIAL java/lang/Object.<init> ()V
+ ALOAD 0
+ ALOAD 1
+ IFNULL L0
+ ALOAD 1
+ GETFIELD jdk8/Artificial$()$Structures.value : I
+ GOTO L1
+ L0
+ FRAME FULL [jdk8/Artificial$()$Structures jdk8/Artificial$()$Structures] [jdk8/Artificial$()$Structures]
+ ICONST_0
+ L1
+ FRAME FULL [jdk8/Artificial$()$Structures jdk8/Artificial$()$Structures] [jdk8/Artificial$()$Structures I]
+ PUTFIELD jdk8/Artificial$()$Structures.value : I
+ RETURN
+ MAXSTACK = 2
+ MAXLOCALS = 2
+
+ // access flags 0x1
+ public clone()Ljdk8/Artificial$()$Structures;
+ NEW jdk8/Artificial$()$Structures
+ DUP
+ ALOAD 0
+ INVOKESPECIAL jdk8/Artificial$()$Structures.<init> (Ljdk8/Artificial$()$Structures;)V
+ ARETURN
+ MAXSTACK = 3
+ MAXLOCALS = 1
+
+ // access flags 0x9
+ public static methodType()Ljava/lang/invoke/MethodType;
+ LDC (I)I.class
+ ARETURN
+ MAXSTACK = 1
+ MAXLOCALS = 0
+}
diff --git a/asm-util/src/test/resources/jdk9.module-info.txt b/asm-util/src/test/resources/jdk9.module-info.txt
new file mode 100644
index 00000000..018da57b
--- /dev/null
+++ b/asm-util/src/test/resources/jdk9.module-info.txt
@@ -0,0 +1,27 @@
+ // compiled from: module-info.java
+module pkg { // 1.0
+
+ // main class pkg/A
+ // package pkg/internal
+ // package pkg
+ requires java.compiler;// access flags 0x0
+ // version 9
+ requires java.base;// access flags 0x8000
+ // version 9
+ requires static java.naming;// access flags 0x40
+ // version 9
+ requires transitive java.prefs;// access flags 0x20
+ // version 9
+ exports pkg to// access flags 0x0
+ java.naming,
+ java.compiler;
+ exports pkg/internal to// access flags 0x0
+ java.prefs;
+ opens pkg/internal to// access flags 0x0
+ java.naming,
+ pkg;
+ uses pkg/A;
+ uses java/lang/Integer;
+ provides pkg/A with
+ pkg/internal/AImpl;
+}
diff --git a/asm-util/src/test/resources/sigtest-4.0.txt b/asm-util/src/test/resources/sigtest-4.0.txt
new file mode 100644
index 00000000..b74111aa
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-4.0.txt
@@ -0,0 +1,477 @@
+#Signature file v4.1
+#Version 4.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds end,named
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds checkDataFlow,end,labels,outer,source,start,version
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds end
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds TYPE,class$org$objectweb$asm$Label,endCode,endMethod,handlers,insnCount,labelStatusField,labels,startCode,usedLabels
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds canBeVoid,state,sv,type
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld public final java.util.List text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List getText()
+meth public void print(java.io.PrintWriter)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds valueNumber
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds p
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds pw
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,arrayStack,declaration,exceptions,isInterface,returnType,seenFormalParameter,seenInterface,seenInterfaceBound,seenParameter,separator
+
diff --git a/asm-util/src/test/resources/sigtest-4.1.txt b/asm-util/src/test/resources/sigtest-4.1.txt
new file mode 100644
index 00000000..daf7e01c
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-4.1.txt
@@ -0,0 +1,480 @@
+#Signature file v4.1
+#Version 4.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds end,named
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds checkDataFlow,end,labels,outer,source,start,version
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds end
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds TYPE,access,class$org$objectweb$asm$Label,compressedFrames,endCode,endMethod,expandedFrames,handlers,insnCount,labelStatusField,labels,lastFrame,startCode,usedLabels
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds canBeVoid,state,sv,type
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld public final java.util.List text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List getText()
+meth public void print(java.io.PrintWriter)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds valueNumber
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds p
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds pw
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,arrayStack,declaration,exceptions,isInterface,returnType,seenFormalParameter,seenInterface,seenInterfaceBound,seenParameter,separator
+
diff --git a/asm-util/src/test/resources/sigtest-5.0.txt b/asm-util/src/test/resources/sigtest-5.0.txt
new file mode 100644
index 00000000..8b05e98f
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-5.0.txt
@@ -0,0 +1,532 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds class$org$objectweb$asm$util$ASMifier
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds end,named
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds checkDataFlow,class$org$objectweb$asm$util$CheckClassAdapter,end,labels,outer,source,start,version
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds class$org$objectweb$asm$util$CheckFieldAdapter,end
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds TYPE,access,class$org$objectweb$asm$Label,class$org$objectweb$asm$util$CheckMethodAdapter,compressedFrames,endCode,endMethod,expandedFrames,handlers,insnCount,labelStatusField,labels,lastFrame,startCode,usedLabels
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds canBeVoid,state,sv,type
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld public final java.util.List text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List getText()
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void print(java.io.PrintWriter)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitParameter(java.lang.String,int)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds access,class$org$objectweb$asm$util$Textifier,valueNumber
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds p
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds pw
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,arrayStack,declaration,exceptions,isInterface,returnType,seenFormalParameter,seenInterface,seenInterfaceBound,seenParameter,separator
+
diff --git a/asm-util/src/test/resources/sigtest-6.0.txt b/asm-util/src/test/resources/sigtest-6.0.txt
new file mode 100644
index 00000000..741682ab
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-6.0.txt
@@ -0,0 +1,608 @@
+#Signature file v4.1
+#Version 6.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds end,named
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds checkDataFlow,end,labels,module,outer,source,start,version
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds end
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds TYPE,access,compressedFrames,endCode,endMethod,expandedFrames,handlers,insnCount,labelStatusField,labels,lastFrame,startCode,usedLabels
+
+CLSS public final org.objectweb.asm.util.CheckModuleAdapter
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds end,exportNames,isOpen,openNames,provideNames,requireNames,useNames
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BOUND,CLASS_TYPE,EMPTY,END,FORMAL,PARAM,RETURN,SIMPLE_TYPE,SUPER,canBeVoid,state,sv,type
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.lang.Exception
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds access,valueNumber
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds p
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds pw
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,arrayStack,declaration,exceptions,isInterface,returnType,seenFormalParameter,seenInterface,seenInterfaceBound,seenParameter,separator
+
diff --git a/asm-util/src/test/resources/sigtest-6.1.txt b/asm-util/src/test/resources/sigtest-6.1.txt
new file mode 100644
index 00000000..53f8eecc
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-6.1.txt
@@ -0,0 +1,618 @@
+#Signature file v4.1
+#Version 6.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,END_ARRAY,END_PARAMETERS,NEW_OBJECT_ARRAY,VISIT_END
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,checkDataFlow,labelInsnIndices,version,visitCalled,visitEndCalled,visitModuleCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,INVISIBLE,access,numAnnotationValues
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-7.0.txt b/asm-util/src/test/resources/sigtest-7.0.txt
new file mode 100644
index 00000000..b6e29a1d
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-7.0.txt
@@ -0,0 +1,631 @@
+#Signature file v4.1
+#Version 7.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,END_ARRAY,END_PARAMETERS,NEW_OBJECT_ARRAY,VISIT_END
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,INVISIBLE,access,numAnnotationValues
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-7.1.txt b/asm-util/src/test/resources/sigtest-7.1.txt
new file mode 100644
index 00000000..e2af6d0c
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-7.1.txt
@@ -0,0 +1,642 @@
+#Signature file v4.1
+#Version 7.1
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-7.2.txt b/asm-util/src/test/resources/sigtest-7.2.txt
new file mode 100644
index 00000000..36883632
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-7.2.txt
@@ -0,0 +1,633 @@
+#Signature file v4.1
+#Version 7.2
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-7.3.1.txt b/asm-util/src/test/resources/sigtest-7.3.1.txt
new file mode 100644
index 00000000..7e332842
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-7.3.1.txt
@@ -0,0 +1,660 @@
+#Signature file v4.1
+#Version 7.3.1
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-8.0.1.txt b/asm-util/src/test/resources/sigtest-8.0.1.txt
new file mode 100644
index 00000000..7f09aacd
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-8.0.1.txt
@@ -0,0 +1,683 @@
+#Signature file v4.1
+#Version 8.0.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,RECORD,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer printer
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-9.0.txt b/asm-util/src/test/resources/sigtest-9.0.txt
new file mode 100644
index 00000000..2799a25f
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-9.0.txt
@@ -0,0 +1,689 @@
+#Signature file v4.1
+#Version 9.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,RECORD,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer printer
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-9.1.txt b/asm-util/src/test/resources/sigtest-9.1.txt
new file mode 100644
index 00000000..364af9e0
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-9.1.txt
@@ -0,0 +1,689 @@
+#Signature file v4.1
+#Version 9.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,RECORD,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer printer
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-9.2.txt b/asm-util/src/test/resources/sigtest-9.2.txt
new file mode 100644
index 00000000..0dcb2ffe
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-9.2.txt
@@ -0,0 +1,689 @@
+#Signature file v4.1
+#Version 9.2
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,RECORD,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer printer
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm-util/src/test/resources/sigtest-9.4.txt b/asm-util/src/test/resources/sigtest-9.4.txt
new file mode 100644
index 00000000..a15cc124
--- /dev/null
+++ b/asm-util/src/test/resources/sigtest-9.4.txt
@@ -0,0 +1,694 @@
+#Signature file v4.1
+#Version 9.4
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor getDelegate()
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.ClassVisitor getDelegate()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.MethodVisitor getDelegate()
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor getDelegate()
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.RecordComponentVisitor delegate
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons protected init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.util.ASMifier
+cons protected init(int,java.lang.String,int)
+cons public init()
+fld protected final int id
+fld protected final java.lang.String name
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+meth protected org.objectweb.asm.util.ASMifier createASMifier(java.lang.String,int)
+meth protected void appendConstant(java.lang.Object)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth protected void declareLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.ASMifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.ASMifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.ASMifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.ASMifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.ASMifier visitTypeAnnotation(java.lang.String,int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds ACCESS_CLASS,ACCESS_FIELD,ACCESS_INNER,ACCESS_MODULE,ANNOTATION_VISITOR,ANNOTATION_VISITOR0,CLASS_VERSIONS,COMMA,END_ARRAY,END_PARAMETERS,FRAME_TYPES,NEW_OBJECT_ARRAY,USAGE,VISIT_END
+
+CLSS public abstract interface org.objectweb.asm.util.ASMifierSupport
+meth public abstract void asmify(java.lang.StringBuilder,java.lang.String,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public org.objectweb.asm.util.CheckAnnotationAdapter
+cons public init(org.objectweb.asm.AnnotationVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds useNamedValue,visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckClassAdapter
+cons protected init(int,org.objectweb.asm.ClassVisitor,boolean)
+cons public init(org.objectweb.asm.ClassVisitor)
+cons public init(org.objectweb.asm.ClassVisitor,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public static void checkClassSignature(java.lang.String)
+meth public static void checkFieldSignature(java.lang.String)
+meth public static void checkMethodSignature(java.lang.String)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public static void verify(org.objectweb.asm.ClassReader,boolean,java.io.PrintWriter)
+meth public static void verify(org.objectweb.asm.ClassReader,java.lang.ClassLoader,boolean,java.io.PrintWriter)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ERROR_AT,USAGE,checkDataFlow,labelInsnIndices,nestMemberPackageName,version,visitCalled,visitEndCalled,visitModuleCalled,visitNestHostCalled,visitOuterClassCalled,visitSourceCalled
+
+CLSS public org.objectweb.asm.util.CheckFieldAdapter
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+cons public init(org.objectweb.asm.FieldVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckMethodAdapter
+cons protected init(int,int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons protected init(int,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(int,java.lang.String,java.lang.String,org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+cons public init(org.objectweb.asm.MethodVisitor)
+cons public init(org.objectweb.asm.MethodVisitor,java.util.Map<org.objectweb.asm.Label,java.lang.Integer>)
+fld public int version
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+hfds END_LABEL,INVALID,INVALID_DESCRIPTOR,INVALID_LOCAL_VARIABLE_INDEX,INVALID_TYPE_REFERENCE,MUST_NOT_BE_NULL_OR_EMPTY,OPCODE_METHODS,START_LABEL,access,handlers,insnCount,invisibleAnnotableParameterCount,labelInsnIndices,lastFrameInsnIndex,numCompressedFrames,numExpandedFrames,referencedLabels,visibleAnnotableParameterCount,visitCodeCalled,visitEndCalled,visitMaxCalled
+hcls Method,MethodWriterWrapper
+
+CLSS public org.objectweb.asm.util.CheckModuleAdapter
+cons protected init(int,org.objectweb.asm.ModuleVisitor,boolean)
+cons public init(org.objectweb.asm.ModuleVisitor,boolean)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+hfds classVersion,exportedPackages,isOpen,openedPackages,providedServices,requiredModules,usedServices,visitEndCalled
+hcls NameSet
+
+CLSS public org.objectweb.asm.util.CheckRecordComponentAdapter
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+cons public init(org.objectweb.asm.RecordComponentVisitor)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+hfds visitEndCalled
+
+CLSS public org.objectweb.asm.util.CheckSignatureAdapter
+cons protected init(int,int,org.objectweb.asm.signature.SignatureVisitor)
+cons public init(int,org.objectweb.asm.signature.SignatureVisitor)
+fld public final static int CLASS_SIGNATURE = 0
+fld public final static int METHOD_SIGNATURE = 1
+fld public final static int TYPE_SIGNATURE = 2
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds INVALID,VISIT_CLASS_BOUND_STATES,VISIT_EXCEPTION_TYPE_STATES,VISIT_FORMAL_TYPE_PARAMETER_STATES,VISIT_INTERFACE_BOUND_STATES,VISIT_INTERFACE_STATES,VISIT_PARAMETER_TYPE_STATES,VISIT_RETURN_TYPE_STATES,VISIT_SUPER_CLASS_STATES,canBeVoid,signatureVisitor,state,type
+hcls State
+
+CLSS public abstract org.objectweb.asm.util.Printer
+cons protected init(int)
+fld protected final int api
+fld protected final java.lang.StringBuilder stringBuilder
+fld public final java.util.List<java.lang.Object> text
+fld public final static java.lang.String[] HANDLE_TAG
+fld public final static java.lang.String[] OPCODES
+fld public final static java.lang.String[] TYPES
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public abstract !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public abstract !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public abstract org.objectweb.asm.util.Printer visitAnnotation(java.lang.String,java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitAnnotationDefault()
+meth public abstract org.objectweb.asm.util.Printer visitArray(java.lang.String)
+meth public abstract org.objectweb.asm.util.Printer visitClassAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public abstract org.objectweb.asm.util.Printer visitFieldAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract org.objectweb.asm.util.Printer visitMethodAnnotation(java.lang.String,boolean)
+meth public abstract org.objectweb.asm.util.Printer visitParameterAnnotation(int,java.lang.String,boolean)
+meth public abstract void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public abstract void visit(java.lang.String,java.lang.Object)
+meth public abstract void visitAnnotationEnd()
+meth public abstract void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitClassEnd()
+meth public abstract void visitCode()
+meth public abstract void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitFieldEnd()
+meth public abstract void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public abstract void visitIincInsn(int,int)
+meth public abstract void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public abstract void visitInsn(int)
+meth public abstract void visitIntInsn(int,int)
+meth public abstract void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public abstract void visitLabel(org.objectweb.asm.Label)
+meth public abstract void visitLdcInsn(java.lang.Object)
+meth public abstract void visitLineNumber(int,org.objectweb.asm.Label)
+meth public abstract void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public abstract void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public abstract void visitMaxs(int,int)
+meth public abstract void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public abstract void visitMethodEnd()
+meth public abstract void visitMultiANewArrayInsn(java.lang.String,int)
+meth public abstract void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public abstract void visitSource(java.lang.String,java.lang.String)
+meth public abstract void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public abstract void visitTypeInsn(int,java.lang.String)
+meth public abstract void visitVarInsn(int,int)
+meth public java.util.List<java.lang.Object> getText()
+meth public org.objectweb.asm.util.Printer visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void appendString(java.lang.StringBuilder,java.lang.String)
+meth public void print(java.io.PrintWriter)
+meth public void visitMainClass(java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+hfds UNSUPPORTED_OPERATION
+
+CLSS public org.objectweb.asm.util.Textifier
+cons protected init(int)
+cons public init()
+fld protected java.lang.String ltab
+fld protected java.lang.String tab
+fld protected java.lang.String tab2
+fld protected java.lang.String tab3
+fld protected java.util.Map<org.objectweb.asm.Label,java.lang.String> labelNames
+fld public final static int CLASS_SIGNATURE = 5
+fld public final static int FIELD_DESCRIPTOR = 1
+fld public final static int FIELD_SIGNATURE = 2
+fld public final static int HANDLE_DESCRIPTOR = 9
+fld public final static int INTERNAL_NAME = 0
+fld public final static int METHOD_DESCRIPTOR = 3
+fld public final static int METHOD_SIGNATURE = 4
+meth protected org.objectweb.asm.util.Textifier createTextifier()
+meth protected void appendDescriptor(int,java.lang.String)
+meth protected void appendHandle(org.objectweb.asm.Handle)
+meth protected void appendLabel(org.objectweb.asm.Label)
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.util.Printer visitClassTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitFieldTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitMethodTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Printer visitRecordComponentTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Printer visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotableParameterCount(int,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitAnnotationDefault()
+meth public org.objectweb.asm.util.Textifier visitArray(java.lang.String)
+meth public org.objectweb.asm.util.Textifier visitClassAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.util.Textifier visitFieldAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.util.Textifier visitMethodAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitRecordComponentAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.util.Textifier visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public static void main(java.lang.String[]) throws java.io.IOException
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitAnnotationEnd()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassAttribute(org.objectweb.asm.Attribute)
+meth public void visitClassEnd()
+meth public void visitCode()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFieldAttribute(org.objectweb.asm.Attribute)
+meth public void visitFieldEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMainClass(java.lang.String)
+meth public void visitMaxs(int,int)
+meth public void visitMethodAttribute(org.objectweb.asm.Attribute)
+meth public void visitMethodEnd()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitModuleEnd()
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitRecordComponentAttribute(org.objectweb.asm.Attribute)
+meth public void visitRecordComponentEnd()
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitUse(java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.util.Printer
+hfds CLASS_SUFFIX,DEPRECATED,FRAME_TYPES,INVISIBLE,RECORD,USAGE,access,numAnnotationValues
+
+CLSS public abstract interface org.objectweb.asm.util.TextifierSupport
+meth public abstract void textify(java.lang.StringBuilder,java.util.Map<org.objectweb.asm.Label,java.lang.String>)
+
+CLSS public final org.objectweb.asm.util.TraceAnnotationVisitor
+cons public init(org.objectweb.asm.AnnotationVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr org.objectweb.asm.AnnotationVisitor
+hfds printer
+
+CLSS public final org.objectweb.asm.util.TraceClassVisitor
+cons public init(java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,java.io.PrintWriter)
+cons public init(org.objectweb.asm.ClassVisitor,org.objectweb.asm.util.Printer,java.io.PrintWriter)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds printWriter
+
+CLSS public final org.objectweb.asm.util.TraceFieldVisitor
+cons public init(org.objectweb.asm.FieldVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.FieldVisitor
+
+CLSS public final org.objectweb.asm.util.TraceMethodVisitor
+cons public init(org.objectweb.asm.MethodVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr org.objectweb.asm.MethodVisitor
+
+CLSS public final org.objectweb.asm.util.TraceModuleVisitor
+cons public init(org.objectweb.asm.ModuleVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer p
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr org.objectweb.asm.ModuleVisitor
+
+CLSS public final org.objectweb.asm.util.TraceRecordComponentVisitor
+cons public init(org.objectweb.asm.RecordComponentVisitor,org.objectweb.asm.util.Printer)
+cons public init(org.objectweb.asm.util.Printer)
+fld public final org.objectweb.asm.util.Printer printer
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr org.objectweb.asm.RecordComponentVisitor
+
+CLSS public final org.objectweb.asm.util.TraceSignatureVisitor
+cons public init(int)
+meth public java.lang.String getDeclaration()
+meth public java.lang.String getExceptions()
+meth public java.lang.String getReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds BASE_TYPES,COMMA_SEPARATOR,EXTENDS_SEPARATOR,IMPLEMENTS_SEPARATOR,argumentStack,arrayStack,declaration,exceptions,formalTypeParameterVisited,interfaceBoundVisited,interfaceVisited,isInterface,parameterTypeVisited,returnType,separator
+
diff --git a/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java b/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java
new file mode 100644
index 00000000..ad5e9634
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java
@@ -0,0 +1,168 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java annotation. The methods of this class must be called in the following
+ * order: ( {@code visit} | {@code visitEnum} | {@code visitAnnotation} | {@code visitArray} )*
+ * {@code visitEnd}.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public abstract class AnnotationVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /**
+ * The annotation visitor to which this visitor must delegate method calls. May be {@literal
+ * null}.
+ */
+ protected AnnotationVisitor av;
+
+ /**
+ * Constructs a new {@link AnnotationVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected AnnotationVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link AnnotationVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param annotationVisitor the annotation visitor to which this visitor must delegate method
+ * calls. May be {@literal null}.
+ */
+ protected AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.av = annotationVisitor;
+ }
+
+ /**
+ * The annotation visitor to which this visitor must delegate method calls. May be {@literal
+ * null}.
+ *
+ * @return the annotation visitor to which this visitor must delegate method calls, or {@literal
+ * null}.
+ */
+ public AnnotationVisitor getDelegate() {
+ return av;
+ }
+
+ /**
+ * Visits a primitive value of the annotation.
+ *
+ * @param name the value name.
+ * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link
+ * Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+ * {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This
+ * value can also be an array of byte, boolean, short, char, int, long, float or double values
+ * (this is equivalent to using {@link #visitArray} and visiting each array element in turn,
+ * but is more convenient).
+ */
+ public void visit(final String name, final Object value) {
+ if (av != null) {
+ av.visit(name, value);
+ }
+ }
+
+ /**
+ * Visits an enumeration value of the annotation.
+ *
+ * @param name the value name.
+ * @param descriptor the class descriptor of the enumeration class.
+ * @param value the actual enumeration value.
+ */
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ if (av != null) {
+ av.visitEnum(name, descriptor, value);
+ }
+ }
+
+ /**
+ * Visits a nested annotation value of the annotation.
+ *
+ * @param name the value name.
+ * @param descriptor the class descriptor of the nested annotation class.
+ * @return a visitor to visit the actual nested annotation value, or {@literal null} if this
+ * visitor is not interested in visiting this nested annotation. <i>The nested annotation
+ * value must be fully visited before calling other methods on this annotation visitor</i>.
+ */
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ if (av != null) {
+ return av.visitAnnotation(name, descriptor);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an array value of the annotation. Note that arrays of primitive values (such as byte,
+ * boolean, short, char, int, long, float or double) can be passed as value to {@link #visit
+ * visit}. This is what {@link ClassReader} does for non empty arrays of primitive values.
+ *
+ * @param name the value name.
+ * @return a visitor to visit the actual array value elements, or {@literal null} if this visitor
+ * is not interested in visiting these values. The 'name' parameters passed to the methods of
+ * this visitor are ignored. <i>All the array values must be visited before calling other
+ * methods on this annotation visitor</i>.
+ */
+ public AnnotationVisitor visitArray(final String name) {
+ if (av != null) {
+ return av.visitArray(name);
+ }
+ return null;
+ }
+
+ /** Visits the end of the annotation. */
+ public void visitEnd() {
+ if (av != null) {
+ av.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java b/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java
new file mode 100644
index 00000000..b4538488
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java
@@ -0,0 +1,553 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * An {@link AnnotationVisitor} that generates a corresponding 'annotation' or 'type_annotation'
+ * structure, as defined in the Java Virtual Machine Specification (JVMS). AnnotationWriter
+ * instances can be chained in a doubly linked list, from which Runtime[In]Visible[Type]Annotations
+ * attributes can be generated with the {@link #putAnnotations} method. Similarly, arrays of such
+ * lists can be used to generate Runtime[In]VisibleParameterAnnotations attributes.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16">JVMS
+ * 4.7.16</a>
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20">JVMS
+ * 4.7.20</a>
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+final class AnnotationWriter extends AnnotationVisitor {
+
+ /** Where the constants used in this AnnotationWriter must be stored. */
+ private final SymbolTable symbolTable;
+
+ /**
+ * Whether values are named or not. AnnotationWriter instances used for annotation default and
+ * annotation arrays use unnamed values (i.e. they generate an 'element_value' structure for each
+ * value, instead of an element_name_index followed by an element_value).
+ */
+ private final boolean useNamedValues;
+
+ /**
+ * The 'annotation' or 'type_annotation' JVMS structure corresponding to the annotation values
+ * visited so far. All the fields of these structures, except the last one - the
+ * element_value_pairs array, must be set before this ByteVector is passed to the constructor
+ * (num_element_value_pairs can be set to 0, it is reset to the correct value in {@link
+ * #visitEnd()}). The element_value_pairs array is filled incrementally in the various visit()
+ * methods.
+ *
+ * <p>Note: as an exception to the above rules, for AnnotationDefault attributes (which contain a
+ * single element_value by definition), this ByteVector is initially empty when passed to the
+ * constructor, and {@link #numElementValuePairsOffset} is set to -1.
+ */
+ private final ByteVector annotation;
+
+ /**
+ * The offset in {@link #annotation} where {@link #numElementValuePairs} must be stored (or -1 for
+ * the case of AnnotationDefault attributes).
+ */
+ private final int numElementValuePairsOffset;
+
+ /** The number of element value pairs visited so far. */
+ private int numElementValuePairs;
+
+ /**
+ * The previous AnnotationWriter. This field is used to store the list of annotations of a
+ * Runtime[In]Visible[Type]Annotations attribute. It is unused for nested or array annotations
+ * (annotation values of annotation type), or for AnnotationDefault attributes.
+ */
+ private final AnnotationWriter previousAnnotation;
+
+ /**
+ * The next AnnotationWriter. This field is used to store the list of annotations of a
+ * Runtime[In]Visible[Type]Annotations attribute. It is unused for nested or array annotations
+ * (annotation values of annotation type), or for AnnotationDefault attributes.
+ */
+ private AnnotationWriter nextAnnotation;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructors and factories
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link AnnotationWriter}.
+ *
+ * @param symbolTable where the constants used in this AnnotationWriter must be stored.
+ * @param useNamedValues whether values are named or not. AnnotationDefault and annotation arrays
+ * use unnamed values.
+ * @param annotation where the 'annotation' or 'type_annotation' JVMS structure corresponding to
+ * the visited content must be stored. This ByteVector must already contain all the fields of
+ * the structure except the last one (the element_value_pairs array).
+ * @param previousAnnotation the previously visited annotation of the
+ * Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
+ * {@literal null} in other cases (e.g. nested or array annotations).
+ */
+ AnnotationWriter(
+ final SymbolTable symbolTable,
+ final boolean useNamedValues,
+ final ByteVector annotation,
+ final AnnotationWriter previousAnnotation) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.symbolTable = symbolTable;
+ this.useNamedValues = useNamedValues;
+ this.annotation = annotation;
+ // By hypothesis, num_element_value_pairs is stored in the last unsigned short of 'annotation'.
+ this.numElementValuePairsOffset = annotation.length == 0 ? -1 : annotation.length - 2;
+ this.previousAnnotation = previousAnnotation;
+ if (previousAnnotation != null) {
+ previousAnnotation.nextAnnotation = this;
+ }
+ }
+
+ /**
+ * Creates a new {@link AnnotationWriter} using named values.
+ *
+ * @param symbolTable where the constants used in this AnnotationWriter must be stored.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param previousAnnotation the previously visited annotation of the
+ * Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
+ * {@literal null} in other cases (e.g. nested or array annotations).
+ * @return a new {@link AnnotationWriter} for the given annotation descriptor.
+ */
+ static AnnotationWriter create(
+ final SymbolTable symbolTable,
+ final String descriptor,
+ final AnnotationWriter previousAnnotation) {
+ // Create a ByteVector to hold an 'annotation' JVMS structure.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.
+ ByteVector annotation = new ByteVector();
+ // Write type_index and reserve space for num_element_value_pairs.
+ annotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
+ return new AnnotationWriter(
+ symbolTable, /* useNamedValues = */ true, annotation, previousAnnotation);
+ }
+
+ /**
+ * Creates a new {@link AnnotationWriter} using named values.
+ *
+ * @param symbolTable where the constants used in this AnnotationWriter must be stored.
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
+ * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param previousAnnotation the previously visited annotation of the
+ * Runtime[In]Visible[Type]Annotations attribute to which this annotation belongs, or
+ * {@literal null} in other cases (e.g. nested or array annotations).
+ * @return a new {@link AnnotationWriter} for the given type annotation reference and descriptor.
+ */
+ static AnnotationWriter create(
+ final SymbolTable symbolTable,
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final AnnotationWriter previousAnnotation) {
+ // Create a ByteVector to hold a 'type_annotation' JVMS structure.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.
+ ByteVector typeAnnotation = new ByteVector();
+ // Write target_type, target_info, and target_path.
+ TypeReference.putTarget(typeRef, typeAnnotation);
+ TypePath.put(typePath, typeAnnotation);
+ // Write type_index and reserve space for num_element_value_pairs.
+ typeAnnotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
+ return new AnnotationWriter(
+ symbolTable, /* useNamedValues = */ true, typeAnnotation, previousAnnotation);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visit(final String name, final Object value) {
+ // Case of an element_value with a const_value_index, class_info_index or array_index field.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1.
+ ++numElementValuePairs;
+ if (useNamedValues) {
+ annotation.putShort(symbolTable.addConstantUtf8(name));
+ }
+ if (value instanceof String) {
+ annotation.put12('s', symbolTable.addConstantUtf8((String) value));
+ } else if (value instanceof Byte) {
+ annotation.put12('B', symbolTable.addConstantInteger(((Byte) value).byteValue()).index);
+ } else if (value instanceof Boolean) {
+ int booleanValue = ((Boolean) value).booleanValue() ? 1 : 0;
+ annotation.put12('Z', symbolTable.addConstantInteger(booleanValue).index);
+ } else if (value instanceof Character) {
+ annotation.put12('C', symbolTable.addConstantInteger(((Character) value).charValue()).index);
+ } else if (value instanceof Short) {
+ annotation.put12('S', symbolTable.addConstantInteger(((Short) value).shortValue()).index);
+ } else if (value instanceof Type) {
+ annotation.put12('c', symbolTable.addConstantUtf8(((Type) value).getDescriptor()));
+ } else if (value instanceof byte[]) {
+ byte[] byteArray = (byte[]) value;
+ annotation.put12('[', byteArray.length);
+ for (byte byteValue : byteArray) {
+ annotation.put12('B', symbolTable.addConstantInteger(byteValue).index);
+ }
+ } else if (value instanceof boolean[]) {
+ boolean[] booleanArray = (boolean[]) value;
+ annotation.put12('[', booleanArray.length);
+ for (boolean booleanValue : booleanArray) {
+ annotation.put12('Z', symbolTable.addConstantInteger(booleanValue ? 1 : 0).index);
+ }
+ } else if (value instanceof short[]) {
+ short[] shortArray = (short[]) value;
+ annotation.put12('[', shortArray.length);
+ for (short shortValue : shortArray) {
+ annotation.put12('S', symbolTable.addConstantInteger(shortValue).index);
+ }
+ } else if (value instanceof char[]) {
+ char[] charArray = (char[]) value;
+ annotation.put12('[', charArray.length);
+ for (char charValue : charArray) {
+ annotation.put12('C', symbolTable.addConstantInteger(charValue).index);
+ }
+ } else if (value instanceof int[]) {
+ int[] intArray = (int[]) value;
+ annotation.put12('[', intArray.length);
+ for (int intValue : intArray) {
+ annotation.put12('I', symbolTable.addConstantInteger(intValue).index);
+ }
+ } else if (value instanceof long[]) {
+ long[] longArray = (long[]) value;
+ annotation.put12('[', longArray.length);
+ for (long longValue : longArray) {
+ annotation.put12('J', symbolTable.addConstantLong(longValue).index);
+ }
+ } else if (value instanceof float[]) {
+ float[] floatArray = (float[]) value;
+ annotation.put12('[', floatArray.length);
+ for (float floatValue : floatArray) {
+ annotation.put12('F', symbolTable.addConstantFloat(floatValue).index);
+ }
+ } else if (value instanceof double[]) {
+ double[] doubleArray = (double[]) value;
+ annotation.put12('[', doubleArray.length);
+ for (double doubleValue : doubleArray) {
+ annotation.put12('D', symbolTable.addConstantDouble(doubleValue).index);
+ }
+ } else {
+ Symbol symbol = symbolTable.addConstant(value);
+ annotation.put12(".s.IFJDCS".charAt(symbol.tag), symbol.index);
+ }
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ // Case of an element_value with an enum_const_value field.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1.
+ ++numElementValuePairs;
+ if (useNamedValues) {
+ annotation.putShort(symbolTable.addConstantUtf8(name));
+ }
+ annotation
+ .put12('e', symbolTable.addConstantUtf8(descriptor))
+ .putShort(symbolTable.addConstantUtf8(value));
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ // Case of an element_value with an annotation_value field.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1.
+ ++numElementValuePairs;
+ if (useNamedValues) {
+ annotation.putShort(symbolTable.addConstantUtf8(name));
+ }
+ // Write tag and type_index, and reserve 2 bytes for num_element_value_pairs.
+ annotation.put12('@', symbolTable.addConstantUtf8(descriptor)).putShort(0);
+ return new AnnotationWriter(symbolTable, /* useNamedValues = */ true, annotation, null);
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ // Case of an element_value with an array_value field.
+ // https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1
+ ++numElementValuePairs;
+ if (useNamedValues) {
+ annotation.putShort(symbolTable.addConstantUtf8(name));
+ }
+ // Write tag, and reserve 2 bytes for num_values. Here we take advantage of the fact that the
+ // end of an element_value of array type is similar to the end of an 'annotation' structure: an
+ // unsigned short num_values followed by num_values element_value, versus an unsigned short
+ // num_element_value_pairs, followed by num_element_value_pairs { element_name_index,
+ // element_value } tuples. This allows us to use an AnnotationWriter with unnamed values to
+ // visit the array elements. Its num_element_value_pairs will correspond to the number of array
+ // elements and will be stored in what is in fact num_values.
+ annotation.put12('[', 0);
+ return new AnnotationWriter(symbolTable, /* useNamedValues = */ false, annotation, null);
+ }
+
+ @Override
+ public void visitEnd() {
+ if (numElementValuePairsOffset != -1) {
+ byte[] data = annotation.data;
+ data[numElementValuePairsOffset] = (byte) (numElementValuePairs >>> 8);
+ data[numElementValuePairsOffset + 1] = (byte) numElementValuePairs;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the size of a Runtime[In]Visible[Type]Annotations attribute containing this annotation
+ * and all its <i>predecessors</i> (see {@link #previousAnnotation}. Also adds the attribute name
+ * to the constant pool of the class (if not null).
+ *
+ * @param attributeName one of "Runtime[In]Visible[Type]Annotations", or {@literal null}.
+ * @return the size in bytes of a Runtime[In]Visible[Type]Annotations attribute containing this
+ * annotation and all its predecessors. This includes the size of the attribute_name_index and
+ * attribute_length fields.
+ */
+ int computeAnnotationsSize(final String attributeName) {
+ if (attributeName != null) {
+ symbolTable.addConstantUtf8(attributeName);
+ }
+ // The attribute_name_index, attribute_length and num_annotations fields use 8 bytes.
+ int attributeSize = 8;
+ AnnotationWriter annotationWriter = this;
+ while (annotationWriter != null) {
+ attributeSize += annotationWriter.annotation.length;
+ annotationWriter = annotationWriter.previousAnnotation;
+ }
+ return attributeSize;
+ }
+
+ /**
+ * Returns the size of the Runtime[In]Visible[Type]Annotations attributes containing the given
+ * annotations and all their <i>predecessors</i> (see {@link #previousAnnotation}. Also adds the
+ * attribute names to the constant pool of the class (if not null).
+ *
+ * @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
+ * class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
+ * {@literal null}.
+ * @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
+ * method or class. The previous ones can be accessed with the {@link #previousAnnotation}
+ * field. May be {@literal null}.
+ * @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
+ * field, method or class. The previous ones can be accessed with the {@link
+ * #previousAnnotation} field. May be {@literal null}.
+ * @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
+ * field, method or class field. The previous ones can be accessed with the {@link
+ * #previousAnnotation} field. May be {@literal null}.
+ * @return the size in bytes of a Runtime[In]Visible[Type]Annotations attribute containing the
+ * given annotations and all their predecessors. This includes the size of the
+ * attribute_name_index and attribute_length fields.
+ */
+ static int computeAnnotationsSize(
+ final AnnotationWriter lastRuntimeVisibleAnnotation,
+ final AnnotationWriter lastRuntimeInvisibleAnnotation,
+ final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
+ final AnnotationWriter lastRuntimeInvisibleTypeAnnotation) {
+ int size = 0;
+ if (lastRuntimeVisibleAnnotation != null) {
+ size +=
+ lastRuntimeVisibleAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_ANNOTATIONS);
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ size +=
+ lastRuntimeInvisibleAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_ANNOTATIONS);
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ size +=
+ lastRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ size +=
+ lastRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+ }
+ return size;
+ }
+
+ /**
+ * Puts a Runtime[In]Visible[Type]Annotations attribute containing this annotations and all its
+ * <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector. Annotations are
+ * put in the same order they have been visited.
+ *
+ * @param attributeNameIndex the constant pool index of the attribute name (one of
+ * "Runtime[In]Visible[Type]Annotations").
+ * @param output where the attribute must be put.
+ */
+ void putAnnotations(final int attributeNameIndex, final ByteVector output) {
+ int attributeLength = 2; // For num_annotations.
+ int numAnnotations = 0;
+ AnnotationWriter annotationWriter = this;
+ AnnotationWriter firstAnnotation = null;
+ while (annotationWriter != null) {
+ // In case the user forgot to call visitEnd().
+ annotationWriter.visitEnd();
+ attributeLength += annotationWriter.annotation.length;
+ numAnnotations++;
+ firstAnnotation = annotationWriter;
+ annotationWriter = annotationWriter.previousAnnotation;
+ }
+ output.putShort(attributeNameIndex);
+ output.putInt(attributeLength);
+ output.putShort(numAnnotations);
+ annotationWriter = firstAnnotation;
+ while (annotationWriter != null) {
+ output.putByteArray(annotationWriter.annotation.data, 0, annotationWriter.annotation.length);
+ annotationWriter = annotationWriter.nextAnnotation;
+ }
+ }
+
+ /**
+ * Puts the Runtime[In]Visible[Type]Annotations attributes containing the given annotations and
+ * all their <i>predecessors</i> (see {@link #previousAnnotation} in the given ByteVector.
+ * Annotations are put in the same order they have been visited.
+ *
+ * @param symbolTable where the constants used in the AnnotationWriter instances are stored.
+ * @param lastRuntimeVisibleAnnotation The last runtime visible annotation of a field, method or
+ * class. The previous ones can be accessed with the {@link #previousAnnotation} field. May be
+ * {@literal null}.
+ * @param lastRuntimeInvisibleAnnotation The last runtime invisible annotation of this a field,
+ * method or class. The previous ones can be accessed with the {@link #previousAnnotation}
+ * field. May be {@literal null}.
+ * @param lastRuntimeVisibleTypeAnnotation The last runtime visible type annotation of this a
+ * field, method or class. The previous ones can be accessed with the {@link
+ * #previousAnnotation} field. May be {@literal null}.
+ * @param lastRuntimeInvisibleTypeAnnotation The last runtime invisible type annotation of a
+ * field, method or class field. The previous ones can be accessed with the {@link
+ * #previousAnnotation} field. May be {@literal null}.
+ * @param output where the attributes must be put.
+ */
+ static void putAnnotations(
+ final SymbolTable symbolTable,
+ final AnnotationWriter lastRuntimeVisibleAnnotation,
+ final AnnotationWriter lastRuntimeInvisibleAnnotation,
+ final AnnotationWriter lastRuntimeVisibleTypeAnnotation,
+ final AnnotationWriter lastRuntimeInvisibleTypeAnnotation,
+ final ByteVector output) {
+ if (lastRuntimeVisibleAnnotation != null) {
+ lastRuntimeVisibleAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_ANNOTATIONS), output);
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ lastRuntimeInvisibleAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_ANNOTATIONS), output);
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ lastRuntimeVisibleTypeAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS), output);
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ lastRuntimeInvisibleTypeAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS), output);
+ }
+ }
+
+ /**
+ * Returns the size of a Runtime[In]VisibleParameterAnnotations attribute containing all the
+ * annotation lists from the given AnnotationWriter sub-array. Also adds the attribute name to the
+ * constant pool of the class.
+ *
+ * @param attributeName one of "Runtime[In]VisibleParameterAnnotations".
+ * @param annotationWriters an array of AnnotationWriter lists (designated by their <i>last</i>
+ * element).
+ * @param annotableParameterCount the number of elements in annotationWriters to take into account
+ * (elements [0..annotableParameterCount[ are taken into account).
+ * @return the size in bytes of a Runtime[In]VisibleParameterAnnotations attribute corresponding
+ * to the given sub-array of AnnotationWriter lists. This includes the size of the
+ * attribute_name_index and attribute_length fields.
+ */
+ static int computeParameterAnnotationsSize(
+ final String attributeName,
+ final AnnotationWriter[] annotationWriters,
+ final int annotableParameterCount) {
+ // Note: attributeName is added to the constant pool by the call to computeAnnotationsSize
+ // below. This assumes that there is at least one non-null element in the annotationWriters
+ // sub-array (which is ensured by the lazy instantiation of this array in MethodWriter).
+ // The attribute_name_index, attribute_length and num_parameters fields use 7 bytes, and each
+ // element of the parameter_annotations array uses 2 bytes for its num_annotations field.
+ int attributeSize = 7 + 2 * annotableParameterCount;
+ for (int i = 0; i < annotableParameterCount; ++i) {
+ AnnotationWriter annotationWriter = annotationWriters[i];
+ attributeSize +=
+ annotationWriter == null ? 0 : annotationWriter.computeAnnotationsSize(attributeName) - 8;
+ }
+ return attributeSize;
+ }
+
+ /**
+ * Puts a Runtime[In]VisibleParameterAnnotations attribute containing all the annotation lists
+ * from the given AnnotationWriter sub-array in the given ByteVector.
+ *
+ * @param attributeNameIndex constant pool index of the attribute name (one of
+ * Runtime[In]VisibleParameterAnnotations).
+ * @param annotationWriters an array of AnnotationWriter lists (designated by their <i>last</i>
+ * element).
+ * @param annotableParameterCount the number of elements in annotationWriters to put (elements
+ * [0..annotableParameterCount[ are put).
+ * @param output where the attribute must be put.
+ */
+ static void putParameterAnnotations(
+ final int attributeNameIndex,
+ final AnnotationWriter[] annotationWriters,
+ final int annotableParameterCount,
+ final ByteVector output) {
+ // The num_parameters field uses 1 byte, and each element of the parameter_annotations array
+ // uses 2 bytes for its num_annotations field.
+ int attributeLength = 1 + 2 * annotableParameterCount;
+ for (int i = 0; i < annotableParameterCount; ++i) {
+ AnnotationWriter annotationWriter = annotationWriters[i];
+ attributeLength +=
+ annotationWriter == null ? 0 : annotationWriter.computeAnnotationsSize(null) - 8;
+ }
+ output.putShort(attributeNameIndex);
+ output.putInt(attributeLength);
+ output.putByte(annotableParameterCount);
+ for (int i = 0; i < annotableParameterCount; ++i) {
+ AnnotationWriter annotationWriter = annotationWriters[i];
+ AnnotationWriter firstAnnotation = null;
+ int numAnnotations = 0;
+ while (annotationWriter != null) {
+ // In case user the forgot to call visitEnd().
+ annotationWriter.visitEnd();
+ numAnnotations++;
+ firstAnnotation = annotationWriter;
+ annotationWriter = annotationWriter.previousAnnotation;
+ }
+ output.putShort(numAnnotations);
+ annotationWriter = firstAnnotation;
+ while (annotationWriter != null) {
+ output.putByteArray(
+ annotationWriter.annotation.data, 0, annotationWriter.annotation.length);
+ annotationWriter = annotationWriter.nextAnnotation;
+ }
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Attribute.java b/asm/src/main/java/org/objectweb/asm/Attribute.java
new file mode 100644
index 00000000..3d73dc68
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Attribute.java
@@ -0,0 +1,392 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A non standard class, field, method or Code attribute, as defined in the Java Virtual Machine
+ * Specification (JVMS).
+ *
+ * @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7">JVMS
+ * 4.7</a>
+ * @see <a href= "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
+ * 4.7.3</a>
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class Attribute {
+
+ /** The type of this attribute, also called its name in the JVMS. */
+ public final String type;
+
+ /**
+ * The raw content of this attribute, only used for unknown attributes (see {@link #isUnknown()}).
+ * The 6 header bytes of the attribute (attribute_name_index and attribute_length) are <i>not</i>
+ * included.
+ */
+ private byte[] content;
+
+ /**
+ * The next attribute in this attribute list (Attribute instances can be linked via this field to
+ * store a list of class, field, method or Code attributes). May be {@literal null}.
+ */
+ Attribute nextAttribute;
+
+ /**
+ * Constructs a new empty attribute.
+ *
+ * @param type the type of the attribute.
+ */
+ protected Attribute(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns {@literal true} if this type of attribute is unknown. This means that the attribute
+ * content can't be parsed to extract constant pool references, labels, etc. Instead, the
+ * attribute content is read as an opaque byte array, and written back as is. This can lead to
+ * invalid attributes, if the content actually contains constant pool references, labels, or other
+ * symbolic references that need to be updated when there are changes to the constant pool, the
+ * method bytecode, etc. The default implementation of this method always returns {@literal true}.
+ *
+ * @return {@literal true} if this type of attribute is unknown.
+ */
+ public boolean isUnknown() {
+ return true;
+ }
+
+ /**
+ * Returns {@literal true} if this type of attribute is a Code attribute.
+ *
+ * @return {@literal true} if this type of attribute is a Code attribute.
+ */
+ public boolean isCodeAttribute() {
+ return false;
+ }
+
+ /**
+ * Returns the labels corresponding to this attribute.
+ *
+ * @return the labels corresponding to this attribute, or {@literal null} if this attribute is not
+ * a Code attribute that contains labels.
+ */
+ protected Label[] getLabels() {
+ return new Label[0];
+ }
+
+ /**
+ * Reads a {@link #type} attribute. This method must return a <i>new</i> {@link Attribute} object,
+ * of type {@link #type}, corresponding to the 'length' bytes starting at 'offset', in the given
+ * ClassReader.
+ *
+ * @param classReader the class that contains the attribute to be read.
+ * @param offset index of the first byte of the attribute's content in {@link ClassReader}. The 6
+ * attribute header bytes (attribute_name_index and attribute_length) are not taken into
+ * account here.
+ * @param length the length of the attribute's content (excluding the 6 attribute header bytes).
+ * @param charBuffer the buffer to be used to call the ClassReader methods requiring a
+ * 'charBuffer' parameter.
+ * @param codeAttributeOffset index of the first byte of content of the enclosing Code attribute
+ * in {@link ClassReader}, or -1 if the attribute to be read is not a Code attribute. The 6
+ * attribute header bytes (attribute_name_index and attribute_length) are not taken into
+ * account here.
+ * @param labels the labels of the method's code, or {@literal null} if the attribute to be read
+ * is not a Code attribute.
+ * @return a <i>new</i> {@link Attribute} object corresponding to the specified bytes.
+ */
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ Attribute attribute = new Attribute(type);
+ attribute.content = new byte[length];
+ System.arraycopy(classReader.classFileBuffer, offset, attribute.content, 0, length);
+ return attribute;
+ }
+
+ /**
+ * Returns the byte array form of the content of this attribute. The 6 header bytes
+ * (attribute_name_index and attribute_length) must <i>not</i> be added in the returned
+ * ByteVector.
+ *
+ * @param classWriter the class to which this attribute must be added. This parameter can be used
+ * to add the items that corresponds to this attribute to the constant pool of this class.
+ * @param code the bytecode of the method corresponding to this Code attribute, or {@literal null}
+ * if this attribute is not a Code attribute. Corresponds to the 'code' field of the Code
+ * attribute.
+ * @param codeLength the length of the bytecode of the method corresponding to this code
+ * attribute, or 0 if this attribute is not a Code attribute. Corresponds to the 'code_length'
+ * field of the Code attribute.
+ * @param maxStack the maximum stack size of the method corresponding to this Code attribute, or
+ * -1 if this attribute is not a Code attribute.
+ * @param maxLocals the maximum number of local variables of the method corresponding to this code
+ * attribute, or -1 if this attribute is not a Code attribute.
+ * @return the byte array form of this attribute.
+ */
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector(content);
+ }
+
+ /**
+ * Returns the number of attributes of the attribute list that begins with this attribute.
+ *
+ * @return the number of attributes of the attribute list that begins with this attribute.
+ */
+ final int getAttributeCount() {
+ int count = 0;
+ Attribute attribute = this;
+ while (attribute != null) {
+ count += 1;
+ attribute = attribute.nextAttribute;
+ }
+ return count;
+ }
+
+ /**
+ * Returns the total size in bytes of all the attributes in the attribute list that begins with
+ * this attribute. This size includes the 6 header bytes (attribute_name_index and
+ * attribute_length) per attribute. Also adds the attribute type names to the constant pool.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @return the size of all the attributes in this attribute list. This size includes the size of
+ * the attribute headers.
+ */
+ final int computeAttributesSize(final SymbolTable symbolTable) {
+ final byte[] code = null;
+ final int codeLength = 0;
+ final int maxStack = -1;
+ final int maxLocals = -1;
+ return computeAttributesSize(symbolTable, code, codeLength, maxStack, maxLocals);
+ }
+
+ /**
+ * Returns the total size in bytes of all the attributes in the attribute list that begins with
+ * this attribute. This size includes the 6 header bytes (attribute_name_index and
+ * attribute_length) per attribute. Also adds the attribute type names to the constant pool.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @param code the bytecode of the method corresponding to these Code attributes, or {@literal
+ * null} if they are not Code attributes. Corresponds to the 'code' field of the Code
+ * attribute.
+ * @param codeLength the length of the bytecode of the method corresponding to these code
+ * attributes, or 0 if they are not Code attributes. Corresponds to the 'code_length' field of
+ * the Code attribute.
+ * @param maxStack the maximum stack size of the method corresponding to these Code attributes, or
+ * -1 if they are not Code attributes.
+ * @param maxLocals the maximum number of local variables of the method corresponding to these
+ * Code attributes, or -1 if they are not Code attribute.
+ * @return the size of all the attributes in this attribute list. This size includes the size of
+ * the attribute headers.
+ */
+ final int computeAttributesSize(
+ final SymbolTable symbolTable,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ final ClassWriter classWriter = symbolTable.classWriter;
+ int size = 0;
+ Attribute attribute = this;
+ while (attribute != null) {
+ symbolTable.addConstantUtf8(attribute.type);
+ size += 6 + attribute.write(classWriter, code, codeLength, maxStack, maxLocals).length;
+ attribute = attribute.nextAttribute;
+ }
+ return size;
+ }
+
+ /**
+ * Returns the total size in bytes of all the attributes that correspond to the given field,
+ * method or class access flags and signature. This size includes the 6 header bytes
+ * (attribute_name_index and attribute_length) per attribute. Also adds the attribute type names
+ * to the constant pool.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @param accessFlags some field, method or class access flags.
+ * @param signatureIndex the constant pool index of a field, method of class signature.
+ * @return the size of all the attributes in bytes. This size includes the size of the attribute
+ * headers.
+ */
+ static int computeAttributesSize(
+ final SymbolTable symbolTable, final int accessFlags, final int signatureIndex) {
+ int size = 0;
+ // Before Java 1.5, synthetic fields are represented with a Synthetic attribute.
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0
+ && symbolTable.getMajorVersion() < Opcodes.V1_5) {
+ // Synthetic attributes always use 6 bytes.
+ symbolTable.addConstantUtf8(Constants.SYNTHETIC);
+ size += 6;
+ }
+ if (signatureIndex != 0) {
+ // Signature attributes always use 8 bytes.
+ symbolTable.addConstantUtf8(Constants.SIGNATURE);
+ size += 8;
+ }
+ // ACC_DEPRECATED is ASM specific, the ClassFile format uses a Deprecated attribute instead.
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ // Deprecated attributes always use 6 bytes.
+ symbolTable.addConstantUtf8(Constants.DEPRECATED);
+ size += 6;
+ }
+ return size;
+ }
+
+ /**
+ * Puts all the attributes of the attribute list that begins with this attribute, in the given
+ * byte vector. This includes the 6 header bytes (attribute_name_index and attribute_length) per
+ * attribute.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @param output where the attributes must be written.
+ */
+ final void putAttributes(final SymbolTable symbolTable, final ByteVector output) {
+ final byte[] code = null;
+ final int codeLength = 0;
+ final int maxStack = -1;
+ final int maxLocals = -1;
+ putAttributes(symbolTable, code, codeLength, maxStack, maxLocals, output);
+ }
+
+ /**
+ * Puts all the attributes of the attribute list that begins with this attribute, in the given
+ * byte vector. This includes the 6 header bytes (attribute_name_index and attribute_length) per
+ * attribute.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @param code the bytecode of the method corresponding to these Code attributes, or {@literal
+ * null} if they are not Code attributes. Corresponds to the 'code' field of the Code
+ * attribute.
+ * @param codeLength the length of the bytecode of the method corresponding to these code
+ * attributes, or 0 if they are not Code attributes. Corresponds to the 'code_length' field of
+ * the Code attribute.
+ * @param maxStack the maximum stack size of the method corresponding to these Code attributes, or
+ * -1 if they are not Code attributes.
+ * @param maxLocals the maximum number of local variables of the method corresponding to these
+ * Code attributes, or -1 if they are not Code attribute.
+ * @param output where the attributes must be written.
+ */
+ final void putAttributes(
+ final SymbolTable symbolTable,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals,
+ final ByteVector output) {
+ final ClassWriter classWriter = symbolTable.classWriter;
+ Attribute attribute = this;
+ while (attribute != null) {
+ ByteVector attributeContent =
+ attribute.write(classWriter, code, codeLength, maxStack, maxLocals);
+ // Put attribute_name_index and attribute_length.
+ output.putShort(symbolTable.addConstantUtf8(attribute.type)).putInt(attributeContent.length);
+ output.putByteArray(attributeContent.data, 0, attributeContent.length);
+ attribute = attribute.nextAttribute;
+ }
+ }
+
+ /**
+ * Puts all the attributes that correspond to the given field, method or class access flags and
+ * signature, in the given byte vector. This includes the 6 header bytes (attribute_name_index and
+ * attribute_length) per attribute.
+ *
+ * @param symbolTable where the constants used in the attributes must be stored.
+ * @param accessFlags some field, method or class access flags.
+ * @param signatureIndex the constant pool index of a field, method of class signature.
+ * @param output where the attributes must be written.
+ */
+ static void putAttributes(
+ final SymbolTable symbolTable,
+ final int accessFlags,
+ final int signatureIndex,
+ final ByteVector output) {
+ // Before Java 1.5, synthetic fields are represented with a Synthetic attribute.
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0
+ && symbolTable.getMajorVersion() < Opcodes.V1_5) {
+ output.putShort(symbolTable.addConstantUtf8(Constants.SYNTHETIC)).putInt(0);
+ }
+ if (signatureIndex != 0) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.SIGNATURE))
+ .putInt(2)
+ .putShort(signatureIndex);
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ output.putShort(symbolTable.addConstantUtf8(Constants.DEPRECATED)).putInt(0);
+ }
+ }
+
+ /** A set of attribute prototypes (attributes with the same type are considered equal). */
+ static final class Set {
+
+ private static final int SIZE_INCREMENT = 6;
+
+ private int size;
+ private Attribute[] data = new Attribute[SIZE_INCREMENT];
+
+ void addAttributes(final Attribute attributeList) {
+ Attribute attribute = attributeList;
+ while (attribute != null) {
+ if (!contains(attribute)) {
+ add(attribute);
+ }
+ attribute = attribute.nextAttribute;
+ }
+ }
+
+ Attribute[] toArray() {
+ Attribute[] result = new Attribute[size];
+ System.arraycopy(data, 0, result, 0, size);
+ return result;
+ }
+
+ private boolean contains(final Attribute attribute) {
+ for (int i = 0; i < size; ++i) {
+ if (data[i].type.equals(attribute.type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void add(final Attribute attribute) {
+ if (size >= data.length) {
+ Attribute[] newData = new Attribute[data.length + SIZE_INCREMENT];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ }
+ data[size++] = attribute;
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ByteVector.java b/asm/src/main/java/org/objectweb/asm/ByteVector.java
new file mode 100644
index 00000000..385b1776
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ByteVector.java
@@ -0,0 +1,373 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream
+ * on top of a ByteArrayOutputStream, but is more efficient.
+ *
+ * @author Eric Bruneton
+ */
+public class ByteVector {
+
+ /** The content of this vector. Only the first {@link #length} bytes contain real data. */
+ byte[] data;
+
+ /** The actual number of bytes in this vector. */
+ int length;
+
+ /** Constructs a new {@link ByteVector} with a default initial capacity. */
+ public ByteVector() {
+ data = new byte[64];
+ }
+
+ /**
+ * Constructs a new {@link ByteVector} with the given initial capacity.
+ *
+ * @param initialCapacity the initial capacity of the byte vector to be constructed.
+ */
+ public ByteVector(final int initialCapacity) {
+ data = new byte[initialCapacity];
+ }
+
+ /**
+ * Constructs a new {@link ByteVector} from the given initial data.
+ *
+ * @param data the initial data of the new byte vector.
+ */
+ ByteVector(final byte[] data) {
+ this.data = data;
+ this.length = data.length;
+ }
+
+ /**
+ * Returns the actual number of bytes in this vector.
+ *
+ * @return the actual number of bytes in this vector.
+ */
+ public int size() {
+ return length;
+ }
+
+ /**
+ * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
+ *
+ * @param byteValue a byte.
+ * @return this byte vector.
+ */
+ public ByteVector putByte(final int byteValue) {
+ int currentLength = length;
+ if (currentLength + 1 > data.length) {
+ enlarge(1);
+ }
+ data[currentLength++] = (byte) byteValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
+ *
+ * @param byteValue1 a byte.
+ * @param byteValue2 another byte.
+ * @return this byte vector.
+ */
+ final ByteVector put11(final int byteValue1, final int byteValue2) {
+ int currentLength = length;
+ if (currentLength + 2 > data.length) {
+ enlarge(2);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) byteValue1;
+ currentData[currentLength++] = (byte) byteValue2;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
+ *
+ * @param shortValue a short.
+ * @return this byte vector.
+ */
+ public ByteVector putShort(final int shortValue) {
+ int currentLength = length;
+ if (currentLength + 2 > data.length) {
+ enlarge(2);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) (shortValue >>> 8);
+ currentData[currentLength++] = (byte) shortValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if
+ * necessary.
+ *
+ * @param byteValue a byte.
+ * @param shortValue a short.
+ * @return this byte vector.
+ */
+ final ByteVector put12(final int byteValue, final int shortValue) {
+ int currentLength = length;
+ if (currentLength + 3 > data.length) {
+ enlarge(3);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) byteValue;
+ currentData[currentLength++] = (byte) (shortValue >>> 8);
+ currentData[currentLength++] = (byte) shortValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts two bytes and a short into this byte vector. The byte vector is automatically enlarged if
+ * necessary.
+ *
+ * @param byteValue1 a byte.
+ * @param byteValue2 another byte.
+ * @param shortValue a short.
+ * @return this byte vector.
+ */
+ final ByteVector put112(final int byteValue1, final int byteValue2, final int shortValue) {
+ int currentLength = length;
+ if (currentLength + 4 > data.length) {
+ enlarge(4);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) byteValue1;
+ currentData[currentLength++] = (byte) byteValue2;
+ currentData[currentLength++] = (byte) (shortValue >>> 8);
+ currentData[currentLength++] = (byte) shortValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
+ *
+ * @param intValue an int.
+ * @return this byte vector.
+ */
+ public ByteVector putInt(final int intValue) {
+ int currentLength = length;
+ if (currentLength + 4 > data.length) {
+ enlarge(4);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) (intValue >>> 24);
+ currentData[currentLength++] = (byte) (intValue >>> 16);
+ currentData[currentLength++] = (byte) (intValue >>> 8);
+ currentData[currentLength++] = (byte) intValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts one byte and two shorts into this byte vector. The byte vector is automatically enlarged
+ * if necessary.
+ *
+ * @param byteValue a byte.
+ * @param shortValue1 a short.
+ * @param shortValue2 another short.
+ * @return this byte vector.
+ */
+ final ByteVector put122(final int byteValue, final int shortValue1, final int shortValue2) {
+ int currentLength = length;
+ if (currentLength + 5 > data.length) {
+ enlarge(5);
+ }
+ byte[] currentData = data;
+ currentData[currentLength++] = (byte) byteValue;
+ currentData[currentLength++] = (byte) (shortValue1 >>> 8);
+ currentData[currentLength++] = (byte) shortValue1;
+ currentData[currentLength++] = (byte) (shortValue2 >>> 8);
+ currentData[currentLength++] = (byte) shortValue2;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
+ *
+ * @param longValue a long.
+ * @return this byte vector.
+ */
+ public ByteVector putLong(final long longValue) {
+ int currentLength = length;
+ if (currentLength + 8 > data.length) {
+ enlarge(8);
+ }
+ byte[] currentData = data;
+ int intValue = (int) (longValue >>> 32);
+ currentData[currentLength++] = (byte) (intValue >>> 24);
+ currentData[currentLength++] = (byte) (intValue >>> 16);
+ currentData[currentLength++] = (byte) (intValue >>> 8);
+ currentData[currentLength++] = (byte) intValue;
+ intValue = (int) longValue;
+ currentData[currentLength++] = (byte) (intValue >>> 24);
+ currentData[currentLength++] = (byte) (intValue >>> 16);
+ currentData[currentLength++] = (byte) (intValue >>> 8);
+ currentData[currentLength++] = (byte) intValue;
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if
+ * necessary.
+ *
+ * @param stringValue a String whose UTF8 encoded length must be less than 65536.
+ * @return this byte vector.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ public ByteVector putUTF8(final String stringValue) {
+ int charLength = stringValue.length();
+ if (charLength > 65535) {
+ throw new IllegalArgumentException("UTF8 string too large");
+ }
+ int currentLength = length;
+ if (currentLength + 2 + charLength > data.length) {
+ enlarge(2 + charLength);
+ }
+ byte[] currentData = data;
+ // Optimistic algorithm: instead of computing the byte length and then serializing the string
+ // (which requires two loops), we assume the byte length is equal to char length (which is the
+ // most frequent case), and we start serializing the string right away. During the
+ // serialization, if we find that this assumption is wrong, we continue with the general method.
+ currentData[currentLength++] = (byte) (charLength >>> 8);
+ currentData[currentLength++] = (byte) charLength;
+ for (int i = 0; i < charLength; ++i) {
+ char charValue = stringValue.charAt(i);
+ if (charValue >= '\u0001' && charValue <= '\u007F') {
+ currentData[currentLength++] = (byte) charValue;
+ } else {
+ length = currentLength;
+ return encodeUtf8(stringValue, i, 65535);
+ }
+ }
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if
+ * necessary. The string length is encoded in two bytes before the encoded characters, if there is
+ * space for that (i.e. if this.length - offset - 2 &gt;= 0).
+ *
+ * @param stringValue the String to encode.
+ * @param offset the index of the first character to encode. The previous characters are supposed
+ * to have already been encoded, using only one byte per character.
+ * @param maxByteLength the maximum byte length of the encoded string, including the already
+ * encoded characters.
+ * @return this byte vector.
+ */
+ final ByteVector encodeUtf8(final String stringValue, final int offset, final int maxByteLength) {
+ int charLength = stringValue.length();
+ int byteLength = offset;
+ for (int i = offset; i < charLength; ++i) {
+ char charValue = stringValue.charAt(i);
+ if (charValue >= 0x0001 && charValue <= 0x007F) {
+ byteLength++;
+ } else if (charValue <= 0x07FF) {
+ byteLength += 2;
+ } else {
+ byteLength += 3;
+ }
+ }
+ if (byteLength > maxByteLength) {
+ throw new IllegalArgumentException("UTF8 string too large");
+ }
+ // Compute where 'byteLength' must be stored in 'data', and store it at this location.
+ int byteLengthOffset = length - offset - 2;
+ if (byteLengthOffset >= 0) {
+ data[byteLengthOffset] = (byte) (byteLength >>> 8);
+ data[byteLengthOffset + 1] = (byte) byteLength;
+ }
+ if (length + byteLength - offset > data.length) {
+ enlarge(byteLength - offset);
+ }
+ int currentLength = length;
+ for (int i = offset; i < charLength; ++i) {
+ char charValue = stringValue.charAt(i);
+ if (charValue >= 0x0001 && charValue <= 0x007F) {
+ data[currentLength++] = (byte) charValue;
+ } else if (charValue <= 0x07FF) {
+ data[currentLength++] = (byte) (0xC0 | charValue >> 6 & 0x1F);
+ data[currentLength++] = (byte) (0x80 | charValue & 0x3F);
+ } else {
+ data[currentLength++] = (byte) (0xE0 | charValue >> 12 & 0xF);
+ data[currentLength++] = (byte) (0x80 | charValue >> 6 & 0x3F);
+ data[currentLength++] = (byte) (0x80 | charValue & 0x3F);
+ }
+ }
+ length = currentLength;
+ return this;
+ }
+
+ /**
+ * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if
+ * necessary.
+ *
+ * @param byteArrayValue an array of bytes. May be {@literal null} to put {@code byteLength} null
+ * bytes into this byte vector.
+ * @param byteOffset index of the first byte of byteArrayValue that must be copied.
+ * @param byteLength number of bytes of byteArrayValue that must be copied.
+ * @return this byte vector.
+ */
+ public ByteVector putByteArray(
+ final byte[] byteArrayValue, final int byteOffset, final int byteLength) {
+ if (length + byteLength > data.length) {
+ enlarge(byteLength);
+ }
+ if (byteArrayValue != null) {
+ System.arraycopy(byteArrayValue, byteOffset, data, length, byteLength);
+ }
+ length += byteLength;
+ return this;
+ }
+
+ /**
+ * Enlarges this byte vector so that it can receive 'size' more bytes.
+ *
+ * @param size number of additional bytes that this byte vector should be able to receive.
+ */
+ private void enlarge(final int size) {
+ if (length > data.length) {
+ throw new AssertionError("Internal error");
+ }
+ int doubleCapacity = 2 * data.length;
+ int minimalCapacity = length + size;
+ byte[] newData = new byte[doubleCapacity > minimalCapacity ? doubleCapacity : minimalCapacity];
+ System.arraycopy(data, 0, newData, 0, length);
+ data = newData;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ClassReader.java b/asm/src/main/java/org/objectweb/asm/ClassReader.java
new file mode 100644
index 00000000..7f0e4e72
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ClassReader.java
@@ -0,0 +1,3852 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A parser to make a {@link ClassVisitor} visit a ClassFile structure, as defined in the Java
+ * Virtual Machine Specification (JVMS). This class parses the ClassFile content and calls the
+ * appropriate visit methods of a given {@link ClassVisitor} for each field, method and bytecode
+ * instruction encountered.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html">JVMS 4</a>
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ClassReader {
+
+ /**
+ * A flag to skip the Code attributes. If this flag is set the Code attributes are neither parsed
+ * nor visited.
+ */
+ public static final int SKIP_CODE = 1;
+
+ /**
+ * A flag to skip the SourceFile, SourceDebugExtension, LocalVariableTable,
+ * LocalVariableTypeTable, LineNumberTable and MethodParameters attributes. If this flag is set
+ * these attributes are neither parsed nor visited (i.e. {@link ClassVisitor#visitSource}, {@link
+ * MethodVisitor#visitLocalVariable}, {@link MethodVisitor#visitLineNumber} and {@link
+ * MethodVisitor#visitParameter} are not called).
+ */
+ public static final int SKIP_DEBUG = 2;
+
+ /**
+ * A flag to skip the StackMap and StackMapTable attributes. If this flag is set these attributes
+ * are neither parsed nor visited (i.e. {@link MethodVisitor#visitFrame} is not called). This flag
+ * is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is used: it avoids visiting frames
+ * that will be ignored and recomputed from scratch.
+ */
+ public static final int SKIP_FRAMES = 4;
+
+ /**
+ * A flag to expand the stack map frames. By default stack map frames are visited in their
+ * original format (i.e. "expanded" for classes whose version is less than V1_6, and "compressed"
+ * for the other classes). If this flag is set, stack map frames are always visited in expanded
+ * format (this option adds a decompression/compression step in ClassReader and ClassWriter which
+ * degrades performance quite a lot).
+ */
+ public static final int EXPAND_FRAMES = 8;
+
+ /**
+ * A flag to expand the ASM specific instructions into an equivalent sequence of standard bytecode
+ * instructions. When resolving a forward jump it may happen that the signed 2 bytes offset
+ * reserved for it is not sufficient to store the bytecode offset. In this case the jump
+ * instruction is replaced with a temporary ASM specific instruction using an unsigned 2 bytes
+ * offset (see {@link Label#resolve}). This internal flag is used to re-read classes containing
+ * such instructions, in order to replace them with standard instructions. In addition, when this
+ * flag is used, goto_w and jsr_w are <i>not</i> converted into goto and jsr, to make sure that
+ * infinite loops where a goto_w is replaced with a goto in ClassReader and converted back to a
+ * goto_w in ClassWriter cannot occur.
+ */
+ static final int EXPAND_ASM_INSNS = 256;
+
+ /** The maximum size of array to allocate. */
+ private static final int MAX_BUFFER_SIZE = 1024 * 1024;
+
+ /** The size of the temporary byte array used to read class input streams chunk by chunk. */
+ private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
+
+ /**
+ * A byte array containing the JVMS ClassFile structure to be parsed.
+ *
+ * @deprecated Use {@link #readByte(int)} and the other read methods instead. This field will
+ * eventually be deleted.
+ */
+ @Deprecated
+ // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
+ public final byte[] b;
+
+ /** The offset in bytes of the ClassFile's access_flags field. */
+ public final int header;
+
+ /**
+ * A byte array containing the JVMS ClassFile structure to be parsed. <i>The content of this array
+ * must not be modified. This field is intended for {@link Attribute} sub classes, and is normally
+ * not needed by class visitors.</i>
+ *
+ * <p>NOTE: the ClassFile structure can start at any offset within this array, i.e. it does not
+ * necessarily start at offset 0. Use {@link #getItem} and {@link #header} to get correct
+ * ClassFile element offsets within this byte array.
+ */
+ final byte[] classFileBuffer;
+
+ /**
+ * The offset in bytes, in {@link #classFileBuffer}, of each cp_info entry of the ClassFile's
+ * constant_pool array, <i>plus one</i>. In other words, the offset of constant pool entry i is
+ * given by cpInfoOffsets[i] - 1, i.e. its cp_info's tag field is given by b[cpInfoOffsets[i] -
+ * 1].
+ */
+ private final int[] cpInfoOffsets;
+
+ /**
+ * The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
+ * multiple parsing of a given CONSTANT_Utf8 constant pool item.
+ */
+ private final String[] constantUtf8Values;
+
+ /**
+ * The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
+ * cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
+ */
+ private final ConstantDynamic[] constantDynamicValues;
+
+ /**
+ * The start offsets in {@link #classFileBuffer} of each element of the bootstrap_methods array
+ * (in the BootstrapMethods attribute).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23">JVMS
+ * 4.7.23</a>
+ */
+ private final int[] bootstrapMethodOffsets;
+
+ /**
+ * A conservative estimate of the maximum length of the strings contained in the constant pool of
+ * the class.
+ */
+ private final int maxStringLength;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param classFile the JVMS ClassFile structure to be read.
+ */
+ public ClassReader(final byte[] classFile) {
+ this(classFile, 0, classFile.length);
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param classFileBuffer a byte array containing the JVMS ClassFile structure to be read.
+ * @param classFileOffset the offset in byteBuffer of the first byte of the ClassFile to be read.
+ * @param classFileLength the length in bytes of the ClassFile to be read.
+ */
+ public ClassReader(
+ final byte[] classFileBuffer,
+ final int classFileOffset,
+ final int classFileLength) { // NOPMD(UnusedFormalParameter) used for backward compatibility.
+ this(classFileBuffer, classFileOffset, /* checkClassVersion = */ true);
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object. <i>This internal constructor must not be exposed
+ * as a public API</i>.
+ *
+ * @param classFileBuffer a byte array containing the JVMS ClassFile structure to be read.
+ * @param classFileOffset the offset in byteBuffer of the first byte of the ClassFile to be read.
+ * @param checkClassVersion whether to check the class version or not.
+ */
+ ClassReader(
+ final byte[] classFileBuffer, final int classFileOffset, final boolean checkClassVersion) {
+ this.classFileBuffer = classFileBuffer;
+ this.b = classFileBuffer;
+ // Check the class' major_version. This field is after the magic and minor_version fields, which
+ // use 4 and 2 bytes respectively.
+ if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V20) {
+ throw new IllegalArgumentException(
+ "Unsupported class file major version " + readShort(classFileOffset + 6));
+ }
+ // Create the constant pool arrays. The constant_pool_count field is after the magic,
+ // minor_version and major_version fields, which use 4, 2 and 2 bytes respectively.
+ int constantPoolCount = readUnsignedShort(classFileOffset + 8);
+ cpInfoOffsets = new int[constantPoolCount];
+ constantUtf8Values = new String[constantPoolCount];
+ // Compute the offset of each constant pool entry, as well as a conservative estimate of the
+ // maximum length of the constant pool strings. The first constant pool entry is after the
+ // magic, minor_version, major_version and constant_pool_count fields, which use 4, 2, 2 and 2
+ // bytes respectively.
+ int currentCpInfoIndex = 1;
+ int currentCpInfoOffset = classFileOffset + 10;
+ int currentMaxStringLength = 0;
+ boolean hasBootstrapMethods = false;
+ boolean hasConstantDynamic = false;
+ // The offset of the other entries depend on the total size of all the previous entries.
+ while (currentCpInfoIndex < constantPoolCount) {
+ cpInfoOffsets[currentCpInfoIndex++] = currentCpInfoOffset + 1;
+ int cpInfoSize;
+ switch (classFileBuffer[currentCpInfoOffset]) {
+ case Symbol.CONSTANT_FIELDREF_TAG:
+ case Symbol.CONSTANT_METHODREF_TAG:
+ case Symbol.CONSTANT_INTERFACE_METHODREF_TAG:
+ case Symbol.CONSTANT_INTEGER_TAG:
+ case Symbol.CONSTANT_FLOAT_TAG:
+ case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
+ cpInfoSize = 5;
+ break;
+ case Symbol.CONSTANT_DYNAMIC_TAG:
+ cpInfoSize = 5;
+ hasBootstrapMethods = true;
+ hasConstantDynamic = true;
+ break;
+ case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
+ cpInfoSize = 5;
+ hasBootstrapMethods = true;
+ break;
+ case Symbol.CONSTANT_LONG_TAG:
+ case Symbol.CONSTANT_DOUBLE_TAG:
+ cpInfoSize = 9;
+ currentCpInfoIndex++;
+ break;
+ case Symbol.CONSTANT_UTF8_TAG:
+ cpInfoSize = 3 + readUnsignedShort(currentCpInfoOffset + 1);
+ if (cpInfoSize > currentMaxStringLength) {
+ // The size in bytes of this CONSTANT_Utf8 structure provides a conservative estimate
+ // of the length in characters of the corresponding string, and is much cheaper to
+ // compute than this exact length.
+ currentMaxStringLength = cpInfoSize;
+ }
+ break;
+ case Symbol.CONSTANT_METHOD_HANDLE_TAG:
+ cpInfoSize = 4;
+ break;
+ case Symbol.CONSTANT_CLASS_TAG:
+ case Symbol.CONSTANT_STRING_TAG:
+ case Symbol.CONSTANT_METHOD_TYPE_TAG:
+ case Symbol.CONSTANT_PACKAGE_TAG:
+ case Symbol.CONSTANT_MODULE_TAG:
+ cpInfoSize = 3;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ currentCpInfoOffset += cpInfoSize;
+ }
+ maxStringLength = currentMaxStringLength;
+ // The Classfile's access_flags field is just after the last constant pool entry.
+ header = currentCpInfoOffset;
+
+ // Allocate the cache of ConstantDynamic values, if there is at least one.
+ constantDynamicValues = hasConstantDynamic ? new ConstantDynamic[constantPoolCount] : null;
+
+ // Read the BootstrapMethods attribute, if any (only get the offset of each method).
+ bootstrapMethodOffsets =
+ hasBootstrapMethods ? readBootstrapMethodsAttribute(currentMaxStringLength) : null;
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param inputStream an input stream of the JVMS ClassFile structure to be read. This input
+ * stream must contain nothing more than the ClassFile structure itself. It is read from its
+ * current position to its end.
+ * @throws IOException if a problem occurs during reading.
+ */
+ public ClassReader(final InputStream inputStream) throws IOException {
+ this(readStream(inputStream, false));
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param className the fully qualified name of the class to be read. The ClassFile structure is
+ * retrieved with the current class loader's {@link ClassLoader#getSystemResourceAsStream}.
+ * @throws IOException if an exception occurs during reading.
+ */
+ public ClassReader(final String className) throws IOException {
+ this(
+ readStream(
+ ClassLoader.getSystemResourceAsStream(className.replace('.', '/') + ".class"), true));
+ }
+
+ /**
+ * Reads the given input stream and returns its content as a byte array.
+ *
+ * @param inputStream an input stream.
+ * @param close true to close the input stream after reading.
+ * @return the content of the given input stream.
+ * @throws IOException if a problem occurs during reading.
+ */
+ @SuppressWarnings("PMD.UseTryWithResources")
+ private static byte[] readStream(final InputStream inputStream, final boolean close)
+ throws IOException {
+ if (inputStream == null) {
+ throw new IOException("Class not found");
+ }
+ int bufferSize = computeBufferSize(inputStream);
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ byte[] data = new byte[bufferSize];
+ int bytesRead;
+ int readCount = 0;
+ while ((bytesRead = inputStream.read(data, 0, bufferSize)) != -1) {
+ outputStream.write(data, 0, bytesRead);
+ readCount++;
+ }
+ outputStream.flush();
+ if (readCount == 1) {
+ return data;
+ }
+ return outputStream.toByteArray();
+ } finally {
+ if (close) {
+ inputStream.close();
+ }
+ }
+ }
+
+ private static int computeBufferSize(final InputStream inputStream) throws IOException {
+ int expectedLength = inputStream.available();
+ /*
+ * Some implementations can return 0 while holding available data (e.g. new
+ * FileInputStream("/proc/a_file")). Also in some pathological cases a very small number might
+ * be returned, and in this case we use a default size.
+ */
+ if (expectedLength < 256) {
+ return INPUT_STREAM_DATA_CHUNK_SIZE;
+ }
+ return Math.min(expectedLength, MAX_BUFFER_SIZE);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accessors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the class's access flags (see {@link Opcodes}). This value may not reflect Deprecated
+ * and Synthetic flags when bytecode is before 1.5 and those flags are represented by attributes.
+ *
+ * @return the class access flags.
+ * @see ClassVisitor#visit(int, int, String, String, String, String[])
+ */
+ public int getAccess() {
+ return readUnsignedShort(header);
+ }
+
+ /**
+ * Returns the internal name of the class (see {@link Type#getInternalName()}).
+ *
+ * @return the internal class name.
+ * @see ClassVisitor#visit(int, int, String, String, String, String[])
+ */
+ public String getClassName() {
+ // this_class is just after the access_flags field (using 2 bytes).
+ return readClass(header + 2, new char[maxStringLength]);
+ }
+
+ /**
+ * Returns the internal name of the super class (see {@link Type#getInternalName()}). For
+ * interfaces, the super class is {@link Object}.
+ *
+ * @return the internal name of the super class, or {@literal null} for {@link Object} class.
+ * @see ClassVisitor#visit(int, int, String, String, String, String[])
+ */
+ public String getSuperName() {
+ // super_class is after the access_flags and this_class fields (2 bytes each).
+ return readClass(header + 4, new char[maxStringLength]);
+ }
+
+ /**
+ * Returns the internal names of the implemented interfaces (see {@link Type#getInternalName()}).
+ *
+ * @return the internal names of the directly implemented interfaces. Inherited implemented
+ * interfaces are not returned.
+ * @see ClassVisitor#visit(int, int, String, String, String, String[])
+ */
+ public String[] getInterfaces() {
+ // interfaces_count is after the access_flags, this_class and super_class fields (2 bytes each).
+ int currentOffset = header + 6;
+ int interfacesCount = readUnsignedShort(currentOffset);
+ String[] interfaces = new String[interfacesCount];
+ if (interfacesCount > 0) {
+ char[] charBuffer = new char[maxStringLength];
+ for (int i = 0; i < interfacesCount; ++i) {
+ currentOffset += 2;
+ interfaces[i] = readClass(currentOffset, charBuffer);
+ }
+ }
+ return interfaces;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Public methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this
+ * {@link ClassReader}.
+ *
+ * @param classVisitor the visitor that must visit this class.
+ * @param parsingOptions the options to use to parse this class. One or more of {@link
+ * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}.
+ */
+ public void accept(final ClassVisitor classVisitor, final int parsingOptions) {
+ accept(classVisitor, new Attribute[0], parsingOptions);
+ }
+
+ /**
+ * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this
+ * {@link ClassReader}.
+ *
+ * @param classVisitor the visitor that must visit this class.
+ * @param attributePrototypes prototypes of the attributes that must be parsed during the visit of
+ * the class. Any attribute whose type is not equal to the type of one the prototypes will not
+ * be parsed: its byte array value will be passed unchanged to the ClassWriter. <i>This may
+ * corrupt it if this value contains references to the constant pool, or has syntactic or
+ * semantic links with a class element that has been transformed by a class adapter between
+ * the reader and the writer</i>.
+ * @param parsingOptions the options to use to parse this class. One or more of {@link
+ * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}.
+ */
+ public void accept(
+ final ClassVisitor classVisitor,
+ final Attribute[] attributePrototypes,
+ final int parsingOptions) {
+ Context context = new Context();
+ context.attributePrototypes = attributePrototypes;
+ context.parsingOptions = parsingOptions;
+ context.charBuffer = new char[maxStringLength];
+
+ // Read the access_flags, this_class, super_class, interface_count and interfaces fields.
+ char[] charBuffer = context.charBuffer;
+ int currentOffset = header;
+ int accessFlags = readUnsignedShort(currentOffset);
+ String thisClass = readClass(currentOffset + 2, charBuffer);
+ String superClass = readClass(currentOffset + 4, charBuffer);
+ String[] interfaces = new String[readUnsignedShort(currentOffset + 6)];
+ currentOffset += 8;
+ for (int i = 0; i < interfaces.length; ++i) {
+ interfaces[i] = readClass(currentOffset, charBuffer);
+ currentOffset += 2;
+ }
+
+ // Read the class attributes (the variables are ordered as in Section 4.7 of the JVMS).
+ // Attribute offsets exclude the attribute_name_index and attribute_length fields.
+ // - The offset of the InnerClasses attribute, or 0.
+ int innerClassesOffset = 0;
+ // - The offset of the EnclosingMethod attribute, or 0.
+ int enclosingMethodOffset = 0;
+ // - The string corresponding to the Signature attribute, or null.
+ String signature = null;
+ // - The string corresponding to the SourceFile attribute, or null.
+ String sourceFile = null;
+ // - The string corresponding to the SourceDebugExtension attribute, or null.
+ String sourceDebugExtension = null;
+ // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
+ int runtimeVisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
+ int runtimeInvisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
+ int runtimeVisibleTypeAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
+ int runtimeInvisibleTypeAnnotationsOffset = 0;
+ // - The offset of the Module attribute, or 0.
+ int moduleOffset = 0;
+ // - The offset of the ModulePackages attribute, or 0.
+ int modulePackagesOffset = 0;
+ // - The string corresponding to the ModuleMainClass attribute, or null.
+ String moduleMainClass = null;
+ // - The string corresponding to the NestHost attribute, or null.
+ String nestHostClass = null;
+ // - The offset of the NestMembers attribute, or 0.
+ int nestMembersOffset = 0;
+ // - The offset of the PermittedSubclasses attribute, or 0
+ int permittedSubclassesOffset = 0;
+ // - The offset of the Record attribute, or 0.
+ int recordOffset = 0;
+ // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
+ // This list in the <i>reverse order</i> or their order in the ClassFile structure.
+ Attribute attributes = null;
+
+ int currentAttributeOffset = getFirstAttributeOffset();
+ for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentAttributeOffset, charBuffer);
+ int attributeLength = readInt(currentAttributeOffset + 2);
+ currentAttributeOffset += 6;
+ // The tests are sorted in decreasing frequency order (based on frequencies observed on
+ // typical classes).
+ if (Constants.SOURCE_FILE.equals(attributeName)) {
+ sourceFile = readUTF8(currentAttributeOffset, charBuffer);
+ } else if (Constants.INNER_CLASSES.equals(attributeName)) {
+ innerClassesOffset = currentAttributeOffset;
+ } else if (Constants.ENCLOSING_METHOD.equals(attributeName)) {
+ enclosingMethodOffset = currentAttributeOffset;
+ } else if (Constants.NEST_HOST.equals(attributeName)) {
+ nestHostClass = readClass(currentAttributeOffset, charBuffer);
+ } else if (Constants.NEST_MEMBERS.equals(attributeName)) {
+ nestMembersOffset = currentAttributeOffset;
+ } else if (Constants.PERMITTED_SUBCLASSES.equals(attributeName)) {
+ permittedSubclassesOffset = currentAttributeOffset;
+ } else if (Constants.SIGNATURE.equals(attributeName)) {
+ signature = readUTF8(currentAttributeOffset, charBuffer);
+ } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleAnnotationsOffset = currentAttributeOffset;
+ } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleTypeAnnotationsOffset = currentAttributeOffset;
+ } else if (Constants.DEPRECATED.equals(attributeName)) {
+ accessFlags |= Opcodes.ACC_DEPRECATED;
+ } else if (Constants.SYNTHETIC.equals(attributeName)) {
+ accessFlags |= Opcodes.ACC_SYNTHETIC;
+ } else if (Constants.SOURCE_DEBUG_EXTENSION.equals(attributeName)) {
+ if (attributeLength > classFileBuffer.length - currentAttributeOffset) {
+ throw new IllegalArgumentException();
+ }
+ sourceDebugExtension =
+ readUtf(currentAttributeOffset, attributeLength, new char[attributeLength]);
+ } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleAnnotationsOffset = currentAttributeOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleTypeAnnotationsOffset = currentAttributeOffset;
+ } else if (Constants.RECORD.equals(attributeName)) {
+ recordOffset = currentAttributeOffset;
+ accessFlags |= Opcodes.ACC_RECORD;
+ } else if (Constants.MODULE.equals(attributeName)) {
+ moduleOffset = currentAttributeOffset;
+ } else if (Constants.MODULE_MAIN_CLASS.equals(attributeName)) {
+ moduleMainClass = readClass(currentAttributeOffset, charBuffer);
+ } else if (Constants.MODULE_PACKAGES.equals(attributeName)) {
+ modulePackagesOffset = currentAttributeOffset;
+ } else if (!Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
+ // The BootstrapMethods attribute is read in the constructor.
+ Attribute attribute =
+ readAttribute(
+ attributePrototypes,
+ attributeName,
+ currentAttributeOffset,
+ attributeLength,
+ charBuffer,
+ -1,
+ null);
+ attribute.nextAttribute = attributes;
+ attributes = attribute;
+ }
+ currentAttributeOffset += attributeLength;
+ }
+
+ // Visit the class declaration. The minor_version and major_version fields start 6 bytes before
+ // the first constant pool entry, which itself starts at cpInfoOffsets[1] - 1 (by definition).
+ classVisitor.visit(
+ readInt(cpInfoOffsets[1] - 7), accessFlags, thisClass, signature, superClass, interfaces);
+
+ // Visit the SourceFile and SourceDebugExtenstion attributes.
+ if ((parsingOptions & SKIP_DEBUG) == 0
+ && (sourceFile != null || sourceDebugExtension != null)) {
+ classVisitor.visitSource(sourceFile, sourceDebugExtension);
+ }
+
+ // Visit the Module, ModulePackages and ModuleMainClass attributes.
+ if (moduleOffset != 0) {
+ readModuleAttributes(
+ classVisitor, context, moduleOffset, modulePackagesOffset, moduleMainClass);
+ }
+
+ // Visit the NestHost attribute.
+ if (nestHostClass != null) {
+ classVisitor.visitNestHost(nestHostClass);
+ }
+
+ // Visit the EnclosingMethod attribute.
+ if (enclosingMethodOffset != 0) {
+ String className = readClass(enclosingMethodOffset, charBuffer);
+ int methodIndex = readUnsignedShort(enclosingMethodOffset + 2);
+ String name = methodIndex == 0 ? null : readUTF8(cpInfoOffsets[methodIndex], charBuffer);
+ String type = methodIndex == 0 ? null : readUTF8(cpInfoOffsets[methodIndex] + 2, charBuffer);
+ classVisitor.visitOuterClass(className, name, type);
+ }
+
+ // Visit the RuntimeVisibleAnnotations attribute.
+ if (runtimeVisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ classVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleAnnotations attribute.
+ if (runtimeInvisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ classVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeVisibleTypeAnnotations attribute.
+ if (runtimeVisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ classVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleTypeAnnotations attribute.
+ if (runtimeInvisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ classVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the non standard attributes.
+ while (attributes != null) {
+ // Copy and reset the nextAttribute field so that it can also be used in ClassWriter.
+ Attribute nextAttribute = attributes.nextAttribute;
+ attributes.nextAttribute = null;
+ classVisitor.visitAttribute(attributes);
+ attributes = nextAttribute;
+ }
+
+ // Visit the NestedMembers attribute.
+ if (nestMembersOffset != 0) {
+ int numberOfNestMembers = readUnsignedShort(nestMembersOffset);
+ int currentNestMemberOffset = nestMembersOffset + 2;
+ while (numberOfNestMembers-- > 0) {
+ classVisitor.visitNestMember(readClass(currentNestMemberOffset, charBuffer));
+ currentNestMemberOffset += 2;
+ }
+ }
+
+ // Visit the PermittedSubclasses attribute.
+ if (permittedSubclassesOffset != 0) {
+ int numberOfPermittedSubclasses = readUnsignedShort(permittedSubclassesOffset);
+ int currentPermittedSubclassesOffset = permittedSubclassesOffset + 2;
+ while (numberOfPermittedSubclasses-- > 0) {
+ classVisitor.visitPermittedSubclass(
+ readClass(currentPermittedSubclassesOffset, charBuffer));
+ currentPermittedSubclassesOffset += 2;
+ }
+ }
+
+ // Visit the InnerClasses attribute.
+ if (innerClassesOffset != 0) {
+ int numberOfClasses = readUnsignedShort(innerClassesOffset);
+ int currentClassesOffset = innerClassesOffset + 2;
+ while (numberOfClasses-- > 0) {
+ classVisitor.visitInnerClass(
+ readClass(currentClassesOffset, charBuffer),
+ readClass(currentClassesOffset + 2, charBuffer),
+ readUTF8(currentClassesOffset + 4, charBuffer),
+ readUnsignedShort(currentClassesOffset + 6));
+ currentClassesOffset += 8;
+ }
+ }
+
+ // Visit Record components.
+ if (recordOffset != 0) {
+ int recordComponentsCount = readUnsignedShort(recordOffset);
+ recordOffset += 2;
+ while (recordComponentsCount-- > 0) {
+ recordOffset = readRecordComponent(classVisitor, context, recordOffset);
+ }
+ }
+
+ // Visit the fields and methods.
+ int fieldsCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (fieldsCount-- > 0) {
+ currentOffset = readField(classVisitor, context, currentOffset);
+ }
+ int methodsCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (methodsCount-- > 0) {
+ currentOffset = readMethod(classVisitor, context, currentOffset);
+ }
+
+ // Visit the end of the class.
+ classVisitor.visitEnd();
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Methods to parse modules, fields and methods
+ // ----------------------------------------------------------------------------------------------
+
+ /**
+ * Reads the Module, ModulePackages and ModuleMainClass attributes and visit them.
+ *
+ * @param classVisitor the current class visitor
+ * @param context information about the class being parsed.
+ * @param moduleOffset the offset of the Module attribute (excluding the attribute_info's
+ * attribute_name_index and attribute_length fields).
+ * @param modulePackagesOffset the offset of the ModulePackages attribute (excluding the
+ * attribute_info's attribute_name_index and attribute_length fields), or 0.
+ * @param moduleMainClass the string corresponding to the ModuleMainClass attribute, or {@literal
+ * null}.
+ */
+ private void readModuleAttributes(
+ final ClassVisitor classVisitor,
+ final Context context,
+ final int moduleOffset,
+ final int modulePackagesOffset,
+ final String moduleMainClass) {
+ char[] buffer = context.charBuffer;
+
+ // Read the module_name_index, module_flags and module_version_index fields and visit them.
+ int currentOffset = moduleOffset;
+ String moduleName = readModule(currentOffset, buffer);
+ int moduleFlags = readUnsignedShort(currentOffset + 2);
+ String moduleVersion = readUTF8(currentOffset + 4, buffer);
+ currentOffset += 6;
+ ModuleVisitor moduleVisitor = classVisitor.visitModule(moduleName, moduleFlags, moduleVersion);
+ if (moduleVisitor == null) {
+ return;
+ }
+
+ // Visit the ModuleMainClass attribute.
+ if (moduleMainClass != null) {
+ moduleVisitor.visitMainClass(moduleMainClass);
+ }
+
+ // Visit the ModulePackages attribute.
+ if (modulePackagesOffset != 0) {
+ int packageCount = readUnsignedShort(modulePackagesOffset);
+ int currentPackageOffset = modulePackagesOffset + 2;
+ while (packageCount-- > 0) {
+ moduleVisitor.visitPackage(readPackage(currentPackageOffset, buffer));
+ currentPackageOffset += 2;
+ }
+ }
+
+ // Read the 'requires_count' and 'requires' fields.
+ int requiresCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (requiresCount-- > 0) {
+ // Read the requires_index, requires_flags and requires_version fields and visit them.
+ String requires = readModule(currentOffset, buffer);
+ int requiresFlags = readUnsignedShort(currentOffset + 2);
+ String requiresVersion = readUTF8(currentOffset + 4, buffer);
+ currentOffset += 6;
+ moduleVisitor.visitRequire(requires, requiresFlags, requiresVersion);
+ }
+
+ // Read the 'exports_count' and 'exports' fields.
+ int exportsCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (exportsCount-- > 0) {
+ // Read the exports_index, exports_flags, exports_to_count and exports_to_index fields
+ // and visit them.
+ String exports = readPackage(currentOffset, buffer);
+ int exportsFlags = readUnsignedShort(currentOffset + 2);
+ int exportsToCount = readUnsignedShort(currentOffset + 4);
+ currentOffset += 6;
+ String[] exportsTo = null;
+ if (exportsToCount != 0) {
+ exportsTo = new String[exportsToCount];
+ for (int i = 0; i < exportsToCount; ++i) {
+ exportsTo[i] = readModule(currentOffset, buffer);
+ currentOffset += 2;
+ }
+ }
+ moduleVisitor.visitExport(exports, exportsFlags, exportsTo);
+ }
+
+ // Reads the 'opens_count' and 'opens' fields.
+ int opensCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (opensCount-- > 0) {
+ // Read the opens_index, opens_flags, opens_to_count and opens_to_index fields and visit them.
+ String opens = readPackage(currentOffset, buffer);
+ int opensFlags = readUnsignedShort(currentOffset + 2);
+ int opensToCount = readUnsignedShort(currentOffset + 4);
+ currentOffset += 6;
+ String[] opensTo = null;
+ if (opensToCount != 0) {
+ opensTo = new String[opensToCount];
+ for (int i = 0; i < opensToCount; ++i) {
+ opensTo[i] = readModule(currentOffset, buffer);
+ currentOffset += 2;
+ }
+ }
+ moduleVisitor.visitOpen(opens, opensFlags, opensTo);
+ }
+
+ // Read the 'uses_count' and 'uses' fields.
+ int usesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (usesCount-- > 0) {
+ moduleVisitor.visitUse(readClass(currentOffset, buffer));
+ currentOffset += 2;
+ }
+
+ // Read the 'provides_count' and 'provides' fields.
+ int providesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (providesCount-- > 0) {
+ // Read the provides_index, provides_with_count and provides_with_index fields and visit them.
+ String provides = readClass(currentOffset, buffer);
+ int providesWithCount = readUnsignedShort(currentOffset + 2);
+ currentOffset += 4;
+ String[] providesWith = new String[providesWithCount];
+ for (int i = 0; i < providesWithCount; ++i) {
+ providesWith[i] = readClass(currentOffset, buffer);
+ currentOffset += 2;
+ }
+ moduleVisitor.visitProvide(provides, providesWith);
+ }
+
+ // Visit the end of the module attributes.
+ moduleVisitor.visitEnd();
+ }
+
+ /**
+ * Reads a record component and visit it.
+ *
+ * @param classVisitor the current class visitor
+ * @param context information about the class being parsed.
+ * @param recordComponentOffset the offset of the current record component.
+ * @return the offset of the first byte following the record component.
+ */
+ private int readRecordComponent(
+ final ClassVisitor classVisitor, final Context context, final int recordComponentOffset) {
+ char[] charBuffer = context.charBuffer;
+
+ int currentOffset = recordComponentOffset;
+ String name = readUTF8(currentOffset, charBuffer);
+ String descriptor = readUTF8(currentOffset + 2, charBuffer);
+ currentOffset += 4;
+
+ // Read the record component attributes (the variables are ordered as in Section 4.7 of the
+ // JVMS).
+
+ // Attribute offsets exclude the attribute_name_index and attribute_length fields.
+ // - The string corresponding to the Signature attribute, or null.
+ String signature = null;
+ // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
+ int runtimeVisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
+ int runtimeInvisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
+ int runtimeVisibleTypeAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
+ int runtimeInvisibleTypeAnnotationsOffset = 0;
+ // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
+ // This list in the <i>reverse order</i> or their order in the ClassFile structure.
+ Attribute attributes = null;
+
+ int attributesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (attributesCount-- > 0) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentOffset, charBuffer);
+ int attributeLength = readInt(currentOffset + 2);
+ currentOffset += 6;
+ // The tests are sorted in decreasing frequency order (based on frequencies observed on
+ // typical classes).
+ if (Constants.SIGNATURE.equals(attributeName)) {
+ signature = readUTF8(currentOffset, charBuffer);
+ } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleTypeAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleTypeAnnotationsOffset = currentOffset;
+ } else {
+ Attribute attribute =
+ readAttribute(
+ context.attributePrototypes,
+ attributeName,
+ currentOffset,
+ attributeLength,
+ charBuffer,
+ -1,
+ null);
+ attribute.nextAttribute = attributes;
+ attributes = attribute;
+ }
+ currentOffset += attributeLength;
+ }
+
+ RecordComponentVisitor recordComponentVisitor =
+ classVisitor.visitRecordComponent(name, descriptor, signature);
+ if (recordComponentVisitor == null) {
+ return currentOffset;
+ }
+
+ // Visit the RuntimeVisibleAnnotations attribute.
+ if (runtimeVisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleAnnotations attribute.
+ if (runtimeInvisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ recordComponentVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeVisibleTypeAnnotations attribute.
+ if (runtimeVisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ recordComponentVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleTypeAnnotations attribute.
+ if (runtimeInvisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ recordComponentVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the non standard attributes.
+ while (attributes != null) {
+ // Copy and reset the nextAttribute field so that it can also be used in FieldWriter.
+ Attribute nextAttribute = attributes.nextAttribute;
+ attributes.nextAttribute = null;
+ recordComponentVisitor.visitAttribute(attributes);
+ attributes = nextAttribute;
+ }
+
+ // Visit the end of the field.
+ recordComponentVisitor.visitEnd();
+ return currentOffset;
+ }
+
+ /**
+ * Reads a JVMS field_info structure and makes the given visitor visit it.
+ *
+ * @param classVisitor the visitor that must visit the field.
+ * @param context information about the class being parsed.
+ * @param fieldInfoOffset the start offset of the field_info structure.
+ * @return the offset of the first byte following the field_info structure.
+ */
+ private int readField(
+ final ClassVisitor classVisitor, final Context context, final int fieldInfoOffset) {
+ char[] charBuffer = context.charBuffer;
+
+ // Read the access_flags, name_index and descriptor_index fields.
+ int currentOffset = fieldInfoOffset;
+ int accessFlags = readUnsignedShort(currentOffset);
+ String name = readUTF8(currentOffset + 2, charBuffer);
+ String descriptor = readUTF8(currentOffset + 4, charBuffer);
+ currentOffset += 6;
+
+ // Read the field attributes (the variables are ordered as in Section 4.7 of the JVMS).
+ // Attribute offsets exclude the attribute_name_index and attribute_length fields.
+ // - The value corresponding to the ConstantValue attribute, or null.
+ Object constantValue = null;
+ // - The string corresponding to the Signature attribute, or null.
+ String signature = null;
+ // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
+ int runtimeVisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
+ int runtimeInvisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
+ int runtimeVisibleTypeAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
+ int runtimeInvisibleTypeAnnotationsOffset = 0;
+ // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
+ // This list in the <i>reverse order</i> or their order in the ClassFile structure.
+ Attribute attributes = null;
+
+ int attributesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (attributesCount-- > 0) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentOffset, charBuffer);
+ int attributeLength = readInt(currentOffset + 2);
+ currentOffset += 6;
+ // The tests are sorted in decreasing frequency order (based on frequencies observed on
+ // typical classes).
+ if (Constants.CONSTANT_VALUE.equals(attributeName)) {
+ int constantvalueIndex = readUnsignedShort(currentOffset);
+ constantValue = constantvalueIndex == 0 ? null : readConst(constantvalueIndex, charBuffer);
+ } else if (Constants.SIGNATURE.equals(attributeName)) {
+ signature = readUTF8(currentOffset, charBuffer);
+ } else if (Constants.DEPRECATED.equals(attributeName)) {
+ accessFlags |= Opcodes.ACC_DEPRECATED;
+ } else if (Constants.SYNTHETIC.equals(attributeName)) {
+ accessFlags |= Opcodes.ACC_SYNTHETIC;
+ } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleTypeAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleTypeAnnotationsOffset = currentOffset;
+ } else {
+ Attribute attribute =
+ readAttribute(
+ context.attributePrototypes,
+ attributeName,
+ currentOffset,
+ attributeLength,
+ charBuffer,
+ -1,
+ null);
+ attribute.nextAttribute = attributes;
+ attributes = attribute;
+ }
+ currentOffset += attributeLength;
+ }
+
+ // Visit the field declaration.
+ FieldVisitor fieldVisitor =
+ classVisitor.visitField(accessFlags, name, descriptor, signature, constantValue);
+ if (fieldVisitor == null) {
+ return currentOffset;
+ }
+
+ // Visit the RuntimeVisibleAnnotations attribute.
+ if (runtimeVisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ fieldVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleAnnotations attribute.
+ if (runtimeInvisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ fieldVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeVisibleTypeAnnotations attribute.
+ if (runtimeVisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ fieldVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleTypeAnnotations attribute.
+ if (runtimeInvisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ fieldVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the non standard attributes.
+ while (attributes != null) {
+ // Copy and reset the nextAttribute field so that it can also be used in FieldWriter.
+ Attribute nextAttribute = attributes.nextAttribute;
+ attributes.nextAttribute = null;
+ fieldVisitor.visitAttribute(attributes);
+ attributes = nextAttribute;
+ }
+
+ // Visit the end of the field.
+ fieldVisitor.visitEnd();
+ return currentOffset;
+ }
+
+ /**
+ * Reads a JVMS method_info structure and makes the given visitor visit it.
+ *
+ * @param classVisitor the visitor that must visit the method.
+ * @param context information about the class being parsed.
+ * @param methodInfoOffset the start offset of the method_info structure.
+ * @return the offset of the first byte following the method_info structure.
+ */
+ private int readMethod(
+ final ClassVisitor classVisitor, final Context context, final int methodInfoOffset) {
+ char[] charBuffer = context.charBuffer;
+
+ // Read the access_flags, name_index and descriptor_index fields.
+ int currentOffset = methodInfoOffset;
+ context.currentMethodAccessFlags = readUnsignedShort(currentOffset);
+ context.currentMethodName = readUTF8(currentOffset + 2, charBuffer);
+ context.currentMethodDescriptor = readUTF8(currentOffset + 4, charBuffer);
+ currentOffset += 6;
+
+ // Read the method attributes (the variables are ordered as in Section 4.7 of the JVMS).
+ // Attribute offsets exclude the attribute_name_index and attribute_length fields.
+ // - The offset of the Code attribute, or 0.
+ int codeOffset = 0;
+ // - The offset of the Exceptions attribute, or 0.
+ int exceptionsOffset = 0;
+ // - The strings corresponding to the Exceptions attribute, or null.
+ String[] exceptions = null;
+ // - Whether the method has a Synthetic attribute.
+ boolean synthetic = false;
+ // - The constant pool index contained in the Signature attribute, or 0.
+ int signatureIndex = 0;
+ // - The offset of the RuntimeVisibleAnnotations attribute, or 0.
+ int runtimeVisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleAnnotations attribute, or 0.
+ int runtimeInvisibleAnnotationsOffset = 0;
+ // - The offset of the RuntimeVisibleParameterAnnotations attribute, or 0.
+ int runtimeVisibleParameterAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleParameterAnnotations attribute, or 0.
+ int runtimeInvisibleParameterAnnotationsOffset = 0;
+ // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0.
+ int runtimeVisibleTypeAnnotationsOffset = 0;
+ // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0.
+ int runtimeInvisibleTypeAnnotationsOffset = 0;
+ // - The offset of the AnnotationDefault attribute, or 0.
+ int annotationDefaultOffset = 0;
+ // - The offset of the MethodParameters attribute, or 0.
+ int methodParametersOffset = 0;
+ // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
+ // This list in the <i>reverse order</i> or their order in the ClassFile structure.
+ Attribute attributes = null;
+
+ int attributesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (attributesCount-- > 0) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentOffset, charBuffer);
+ int attributeLength = readInt(currentOffset + 2);
+ currentOffset += 6;
+ // The tests are sorted in decreasing frequency order (based on frequencies observed on
+ // typical classes).
+ if (Constants.CODE.equals(attributeName)) {
+ if ((context.parsingOptions & SKIP_CODE) == 0) {
+ codeOffset = currentOffset;
+ }
+ } else if (Constants.EXCEPTIONS.equals(attributeName)) {
+ exceptionsOffset = currentOffset;
+ exceptions = new String[readUnsignedShort(exceptionsOffset)];
+ int currentExceptionOffset = exceptionsOffset + 2;
+ for (int i = 0; i < exceptions.length; ++i) {
+ exceptions[i] = readClass(currentExceptionOffset, charBuffer);
+ currentExceptionOffset += 2;
+ }
+ } else if (Constants.SIGNATURE.equals(attributeName)) {
+ signatureIndex = readUnsignedShort(currentOffset);
+ } else if (Constants.DEPRECATED.equals(attributeName)) {
+ context.currentMethodAccessFlags |= Opcodes.ACC_DEPRECATED;
+ } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleTypeAnnotationsOffset = currentOffset;
+ } else if (Constants.ANNOTATION_DEFAULT.equals(attributeName)) {
+ annotationDefaultOffset = currentOffset;
+ } else if (Constants.SYNTHETIC.equals(attributeName)) {
+ synthetic = true;
+ context.currentMethodAccessFlags |= Opcodes.ACC_SYNTHETIC;
+ } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleTypeAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(attributeName)) {
+ runtimeVisibleParameterAnnotationsOffset = currentOffset;
+ } else if (Constants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(attributeName)) {
+ runtimeInvisibleParameterAnnotationsOffset = currentOffset;
+ } else if (Constants.METHOD_PARAMETERS.equals(attributeName)) {
+ methodParametersOffset = currentOffset;
+ } else {
+ Attribute attribute =
+ readAttribute(
+ context.attributePrototypes,
+ attributeName,
+ currentOffset,
+ attributeLength,
+ charBuffer,
+ -1,
+ null);
+ attribute.nextAttribute = attributes;
+ attributes = attribute;
+ }
+ currentOffset += attributeLength;
+ }
+
+ // Visit the method declaration.
+ MethodVisitor methodVisitor =
+ classVisitor.visitMethod(
+ context.currentMethodAccessFlags,
+ context.currentMethodName,
+ context.currentMethodDescriptor,
+ signatureIndex == 0 ? null : readUtf(signatureIndex, charBuffer),
+ exceptions);
+ if (methodVisitor == null) {
+ return currentOffset;
+ }
+
+ // If the returned MethodVisitor is in fact a MethodWriter, it means there is no method
+ // adapter between the reader and the writer. In this case, it might be possible to copy
+ // the method attributes directly into the writer. If so, return early without visiting
+ // the content of these attributes.
+ if (methodVisitor instanceof MethodWriter) {
+ MethodWriter methodWriter = (MethodWriter) methodVisitor;
+ if (methodWriter.canCopyMethodAttributes(
+ this,
+ synthetic,
+ (context.currentMethodAccessFlags & Opcodes.ACC_DEPRECATED) != 0,
+ readUnsignedShort(methodInfoOffset + 4),
+ signatureIndex,
+ exceptionsOffset)) {
+ methodWriter.setMethodAttributesSource(methodInfoOffset, currentOffset - methodInfoOffset);
+ return currentOffset;
+ }
+ }
+
+ // Visit the MethodParameters attribute.
+ if (methodParametersOffset != 0 && (context.parsingOptions & SKIP_DEBUG) == 0) {
+ int parametersCount = readByte(methodParametersOffset);
+ int currentParameterOffset = methodParametersOffset + 1;
+ while (parametersCount-- > 0) {
+ // Read the name_index and access_flags fields and visit them.
+ methodVisitor.visitParameter(
+ readUTF8(currentParameterOffset, charBuffer),
+ readUnsignedShort(currentParameterOffset + 2));
+ currentParameterOffset += 4;
+ }
+ }
+
+ // Visit the AnnotationDefault attribute.
+ if (annotationDefaultOffset != 0) {
+ AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault();
+ readElementValue(annotationVisitor, annotationDefaultOffset, null, charBuffer);
+ if (annotationVisitor != null) {
+ annotationVisitor.visitEnd();
+ }
+ }
+
+ // Visit the RuntimeVisibleAnnotations attribute.
+ if (runtimeVisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ methodVisitor.visitAnnotation(annotationDescriptor, /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleAnnotations attribute.
+ if (runtimeInvisibleAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ methodVisitor.visitAnnotation(annotationDescriptor, /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeVisibleTypeAnnotations attribute.
+ if (runtimeVisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ methodVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeInvisibleTypeAnnotations attribute.
+ if (runtimeInvisibleTypeAnnotationsOffset != 0) {
+ int numAnnotations = readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
+ int currentAnnotationOffset = runtimeInvisibleTypeAnnotationsOffset + 2;
+ while (numAnnotations-- > 0) {
+ // Parse the target_type, target_info and target_path fields.
+ currentAnnotationOffset = readTypeAnnotationTarget(context, currentAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentAnnotationOffset =
+ readElementValues(
+ methodVisitor.visitTypeAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+
+ // Visit the RuntimeVisibleParameterAnnotations attribute.
+ if (runtimeVisibleParameterAnnotationsOffset != 0) {
+ readParameterAnnotations(
+ methodVisitor, context, runtimeVisibleParameterAnnotationsOffset, /* visible = */ true);
+ }
+
+ // Visit the RuntimeInvisibleParameterAnnotations attribute.
+ if (runtimeInvisibleParameterAnnotationsOffset != 0) {
+ readParameterAnnotations(
+ methodVisitor,
+ context,
+ runtimeInvisibleParameterAnnotationsOffset,
+ /* visible = */ false);
+ }
+
+ // Visit the non standard attributes.
+ while (attributes != null) {
+ // Copy and reset the nextAttribute field so that it can also be used in MethodWriter.
+ Attribute nextAttribute = attributes.nextAttribute;
+ attributes.nextAttribute = null;
+ methodVisitor.visitAttribute(attributes);
+ attributes = nextAttribute;
+ }
+
+ // Visit the Code attribute.
+ if (codeOffset != 0) {
+ methodVisitor.visitCode();
+ readCode(methodVisitor, context, codeOffset);
+ }
+
+ // Visit the end of the method.
+ methodVisitor.visitEnd();
+ return currentOffset;
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Methods to parse a Code attribute
+ // ----------------------------------------------------------------------------------------------
+
+ /**
+ * Reads a JVMS 'Code' attribute and makes the given visitor visit it.
+ *
+ * @param methodVisitor the visitor that must visit the Code attribute.
+ * @param context information about the class being parsed.
+ * @param codeOffset the start offset in {@link #classFileBuffer} of the Code attribute, excluding
+ * its attribute_name_index and attribute_length fields.
+ */
+ private void readCode(
+ final MethodVisitor methodVisitor, final Context context, final int codeOffset) {
+ int currentOffset = codeOffset;
+
+ // Read the max_stack, max_locals and code_length fields.
+ final byte[] classBuffer = classFileBuffer;
+ final char[] charBuffer = context.charBuffer;
+ final int maxStack = readUnsignedShort(currentOffset);
+ final int maxLocals = readUnsignedShort(currentOffset + 2);
+ final int codeLength = readInt(currentOffset + 4);
+ currentOffset += 8;
+ if (codeLength > classFileBuffer.length - currentOffset) {
+ throw new IllegalArgumentException();
+ }
+
+ // Read the bytecode 'code' array to create a label for each referenced instruction.
+ final int bytecodeStartOffset = currentOffset;
+ final int bytecodeEndOffset = currentOffset + codeLength;
+ final Label[] labels = context.currentMethodLabels = new Label[codeLength + 1];
+ while (currentOffset < bytecodeEndOffset) {
+ final int bytecodeOffset = currentOffset - bytecodeStartOffset;
+ final int opcode = classBuffer[currentOffset] & 0xFF;
+ switch (opcode) {
+ case Opcodes.NOP:
+ case Opcodes.ACONST_NULL:
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.IALOAD:
+ case Opcodes.LALOAD:
+ case Opcodes.FALOAD:
+ case Opcodes.DALOAD:
+ case Opcodes.AALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IASTORE:
+ case Opcodes.LASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.DASTORE:
+ case Opcodes.AASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.POP:
+ case Opcodes.POP2:
+ case Opcodes.DUP:
+ case Opcodes.DUP_X1:
+ case Opcodes.DUP_X2:
+ case Opcodes.DUP2:
+ case Opcodes.DUP2_X1:
+ case Opcodes.DUP2_X2:
+ case Opcodes.SWAP:
+ case Opcodes.IADD:
+ case Opcodes.LADD:
+ case Opcodes.FADD:
+ case Opcodes.DADD:
+ case Opcodes.ISUB:
+ case Opcodes.LSUB:
+ case Opcodes.FSUB:
+ case Opcodes.DSUB:
+ case Opcodes.IMUL:
+ case Opcodes.LMUL:
+ case Opcodes.FMUL:
+ case Opcodes.DMUL:
+ case Opcodes.IDIV:
+ case Opcodes.LDIV:
+ case Opcodes.FDIV:
+ case Opcodes.DDIV:
+ case Opcodes.IREM:
+ case Opcodes.LREM:
+ case Opcodes.FREM:
+ case Opcodes.DREM:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.ISHL:
+ case Opcodes.LSHL:
+ case Opcodes.ISHR:
+ case Opcodes.LSHR:
+ case Opcodes.IUSHR:
+ case Opcodes.LUSHR:
+ case Opcodes.IAND:
+ case Opcodes.LAND:
+ case Opcodes.IOR:
+ case Opcodes.LOR:
+ case Opcodes.IXOR:
+ case Opcodes.LXOR:
+ case Opcodes.I2L:
+ case Opcodes.I2F:
+ case Opcodes.I2D:
+ case Opcodes.L2I:
+ case Opcodes.L2F:
+ case Opcodes.L2D:
+ case Opcodes.F2I:
+ case Opcodes.F2L:
+ case Opcodes.F2D:
+ case Opcodes.D2I:
+ case Opcodes.D2L:
+ case Opcodes.D2F:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.LCMP:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.RETURN:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Constants.ILOAD_0:
+ case Constants.ILOAD_1:
+ case Constants.ILOAD_2:
+ case Constants.ILOAD_3:
+ case Constants.LLOAD_0:
+ case Constants.LLOAD_1:
+ case Constants.LLOAD_2:
+ case Constants.LLOAD_3:
+ case Constants.FLOAD_0:
+ case Constants.FLOAD_1:
+ case Constants.FLOAD_2:
+ case Constants.FLOAD_3:
+ case Constants.DLOAD_0:
+ case Constants.DLOAD_1:
+ case Constants.DLOAD_2:
+ case Constants.DLOAD_3:
+ case Constants.ALOAD_0:
+ case Constants.ALOAD_1:
+ case Constants.ALOAD_2:
+ case Constants.ALOAD_3:
+ case Constants.ISTORE_0:
+ case Constants.ISTORE_1:
+ case Constants.ISTORE_2:
+ case Constants.ISTORE_3:
+ case Constants.LSTORE_0:
+ case Constants.LSTORE_1:
+ case Constants.LSTORE_2:
+ case Constants.LSTORE_3:
+ case Constants.FSTORE_0:
+ case Constants.FSTORE_1:
+ case Constants.FSTORE_2:
+ case Constants.FSTORE_3:
+ case Constants.DSTORE_0:
+ case Constants.DSTORE_1:
+ case Constants.DSTORE_2:
+ case Constants.DSTORE_3:
+ case Constants.ASTORE_0:
+ case Constants.ASTORE_1:
+ case Constants.ASTORE_2:
+ case Constants.ASTORE_3:
+ currentOffset += 1;
+ break;
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.GOTO:
+ case Opcodes.JSR:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ createLabel(bytecodeOffset + readShort(currentOffset + 1), labels);
+ currentOffset += 3;
+ break;
+ case Constants.ASM_IFEQ:
+ case Constants.ASM_IFNE:
+ case Constants.ASM_IFLT:
+ case Constants.ASM_IFGE:
+ case Constants.ASM_IFGT:
+ case Constants.ASM_IFLE:
+ case Constants.ASM_IF_ICMPEQ:
+ case Constants.ASM_IF_ICMPNE:
+ case Constants.ASM_IF_ICMPLT:
+ case Constants.ASM_IF_ICMPGE:
+ case Constants.ASM_IF_ICMPGT:
+ case Constants.ASM_IF_ICMPLE:
+ case Constants.ASM_IF_ACMPEQ:
+ case Constants.ASM_IF_ACMPNE:
+ case Constants.ASM_GOTO:
+ case Constants.ASM_JSR:
+ case Constants.ASM_IFNULL:
+ case Constants.ASM_IFNONNULL:
+ createLabel(bytecodeOffset + readUnsignedShort(currentOffset + 1), labels);
+ currentOffset += 3;
+ break;
+ case Constants.GOTO_W:
+ case Constants.JSR_W:
+ case Constants.ASM_GOTO_W:
+ createLabel(bytecodeOffset + readInt(currentOffset + 1), labels);
+ currentOffset += 5;
+ break;
+ case Constants.WIDE:
+ switch (classBuffer[currentOffset + 1] & 0xFF) {
+ case Opcodes.ILOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.ALOAD:
+ case Opcodes.LLOAD:
+ case Opcodes.DLOAD:
+ case Opcodes.ISTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.ASTORE:
+ case Opcodes.LSTORE:
+ case Opcodes.DSTORE:
+ case Opcodes.RET:
+ currentOffset += 4;
+ break;
+ case Opcodes.IINC:
+ currentOffset += 6;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ break;
+ case Opcodes.TABLESWITCH:
+ // Skip 0 to 3 padding bytes.
+ currentOffset += 4 - (bytecodeOffset & 3);
+ // Read the default label and the number of table entries.
+ createLabel(bytecodeOffset + readInt(currentOffset), labels);
+ int numTableEntries = readInt(currentOffset + 8) - readInt(currentOffset + 4) + 1;
+ currentOffset += 12;
+ // Read the table labels.
+ while (numTableEntries-- > 0) {
+ createLabel(bytecodeOffset + readInt(currentOffset), labels);
+ currentOffset += 4;
+ }
+ break;
+ case Opcodes.LOOKUPSWITCH:
+ // Skip 0 to 3 padding bytes.
+ currentOffset += 4 - (bytecodeOffset & 3);
+ // Read the default label and the number of switch cases.
+ createLabel(bytecodeOffset + readInt(currentOffset), labels);
+ int numSwitchCases = readInt(currentOffset + 4);
+ currentOffset += 8;
+ // Read the switch labels.
+ while (numSwitchCases-- > 0) {
+ createLabel(bytecodeOffset + readInt(currentOffset + 4), labels);
+ currentOffset += 8;
+ }
+ break;
+ case Opcodes.ILOAD:
+ case Opcodes.LLOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.DLOAD:
+ case Opcodes.ALOAD:
+ case Opcodes.ISTORE:
+ case Opcodes.LSTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.DSTORE:
+ case Opcodes.ASTORE:
+ case Opcodes.RET:
+ case Opcodes.BIPUSH:
+ case Opcodes.NEWARRAY:
+ case Opcodes.LDC:
+ currentOffset += 2;
+ break;
+ case Opcodes.SIPUSH:
+ case Constants.LDC_W:
+ case Constants.LDC2_W:
+ case Opcodes.GETSTATIC:
+ case Opcodes.PUTSTATIC:
+ case Opcodes.GETFIELD:
+ case Opcodes.PUTFIELD:
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.NEW:
+ case Opcodes.ANEWARRAY:
+ case Opcodes.CHECKCAST:
+ case Opcodes.INSTANCEOF:
+ case Opcodes.IINC:
+ currentOffset += 3;
+ break;
+ case Opcodes.INVOKEINTERFACE:
+ case Opcodes.INVOKEDYNAMIC:
+ currentOffset += 5;
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ currentOffset += 4;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // Read the 'exception_table_length' and 'exception_table' field to create a label for each
+ // referenced instruction, and to make methodVisitor visit the corresponding try catch blocks.
+ int exceptionTableLength = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (exceptionTableLength-- > 0) {
+ Label start = createLabel(readUnsignedShort(currentOffset), labels);
+ Label end = createLabel(readUnsignedShort(currentOffset + 2), labels);
+ Label handler = createLabel(readUnsignedShort(currentOffset + 4), labels);
+ String catchType = readUTF8(cpInfoOffsets[readUnsignedShort(currentOffset + 6)], charBuffer);
+ currentOffset += 8;
+ methodVisitor.visitTryCatchBlock(start, end, handler, catchType);
+ }
+
+ // Read the Code attributes to create a label for each referenced instruction (the variables
+ // are ordered as in Section 4.7 of the JVMS). Attribute offsets exclude the
+ // attribute_name_index and attribute_length fields.
+ // - The offset of the current 'stack_map_frame' in the StackMap[Table] attribute, or 0.
+ // Initially, this is the offset of the first 'stack_map_frame' entry. Then this offset is
+ // updated after each stack_map_frame is read.
+ int stackMapFrameOffset = 0;
+ // - The end offset of the StackMap[Table] attribute, or 0.
+ int stackMapTableEndOffset = 0;
+ // - Whether the stack map frames are compressed (i.e. in a StackMapTable) or not.
+ boolean compressedFrames = true;
+ // - The offset of the LocalVariableTable attribute, or 0.
+ int localVariableTableOffset = 0;
+ // - The offset of the LocalVariableTypeTable attribute, or 0.
+ int localVariableTypeTableOffset = 0;
+ // - The offset of each 'type_annotation' entry in the RuntimeVisibleTypeAnnotations
+ // attribute, or null.
+ int[] visibleTypeAnnotationOffsets = null;
+ // - The offset of each 'type_annotation' entry in the RuntimeInvisibleTypeAnnotations
+ // attribute, or null.
+ int[] invisibleTypeAnnotationOffsets = null;
+ // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field).
+ // This list in the <i>reverse order</i> or their order in the ClassFile structure.
+ Attribute attributes = null;
+
+ int attributesCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (attributesCount-- > 0) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentOffset, charBuffer);
+ int attributeLength = readInt(currentOffset + 2);
+ currentOffset += 6;
+ if (Constants.LOCAL_VARIABLE_TABLE.equals(attributeName)) {
+ if ((context.parsingOptions & SKIP_DEBUG) == 0) {
+ localVariableTableOffset = currentOffset;
+ // Parse the attribute to find the corresponding (debug only) labels.
+ int currentLocalVariableTableOffset = currentOffset;
+ int localVariableTableLength = readUnsignedShort(currentLocalVariableTableOffset);
+ currentLocalVariableTableOffset += 2;
+ while (localVariableTableLength-- > 0) {
+ int startPc = readUnsignedShort(currentLocalVariableTableOffset);
+ createDebugLabel(startPc, labels);
+ int length = readUnsignedShort(currentLocalVariableTableOffset + 2);
+ createDebugLabel(startPc + length, labels);
+ // Skip the name_index, descriptor_index and index fields (2 bytes each).
+ currentLocalVariableTableOffset += 10;
+ }
+ }
+ } else if (Constants.LOCAL_VARIABLE_TYPE_TABLE.equals(attributeName)) {
+ localVariableTypeTableOffset = currentOffset;
+ // Here we do not extract the labels corresponding to the attribute content. We assume they
+ // are the same or a subset of those of the LocalVariableTable attribute.
+ } else if (Constants.LINE_NUMBER_TABLE.equals(attributeName)) {
+ if ((context.parsingOptions & SKIP_DEBUG) == 0) {
+ // Parse the attribute to find the corresponding (debug only) labels.
+ int currentLineNumberTableOffset = currentOffset;
+ int lineNumberTableLength = readUnsignedShort(currentLineNumberTableOffset);
+ currentLineNumberTableOffset += 2;
+ while (lineNumberTableLength-- > 0) {
+ int startPc = readUnsignedShort(currentLineNumberTableOffset);
+ int lineNumber = readUnsignedShort(currentLineNumberTableOffset + 2);
+ currentLineNumberTableOffset += 4;
+ createDebugLabel(startPc, labels);
+ labels[startPc].addLineNumber(lineNumber);
+ }
+ }
+ } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ visibleTypeAnnotationOffsets =
+ readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ true);
+ // Here we do not extract the labels corresponding to the attribute content. This would
+ // require a full parsing of the attribute, which would need to be repeated when parsing
+ // the bytecode instructions (see below). Instead, the content of the attribute is read one
+ // type annotation at a time (i.e. after a type annotation has been visited, the next type
+ // annotation is read), and the labels it contains are also extracted one annotation at a
+ // time. This assumes that type annotations are ordered by increasing bytecode offset.
+ } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) {
+ invisibleTypeAnnotationOffsets =
+ readTypeAnnotations(methodVisitor, context, currentOffset, /* visible = */ false);
+ // Same comment as above for the RuntimeVisibleTypeAnnotations attribute.
+ } else if (Constants.STACK_MAP_TABLE.equals(attributeName)) {
+ if ((context.parsingOptions & SKIP_FRAMES) == 0) {
+ stackMapFrameOffset = currentOffset + 2;
+ stackMapTableEndOffset = currentOffset + attributeLength;
+ }
+ // Here we do not extract the labels corresponding to the attribute content. This would
+ // require a full parsing of the attribute, which would need to be repeated when parsing
+ // the bytecode instructions (see below). Instead, the content of the attribute is read one
+ // frame at a time (i.e. after a frame has been visited, the next frame is read), and the
+ // labels it contains are also extracted one frame at a time. Thanks to the ordering of
+ // frames, having only a "one frame lookahead" is not a problem, i.e. it is not possible to
+ // see an offset smaller than the offset of the current instruction and for which no Label
+ // exist. Except for UNINITIALIZED type offsets. We solve this by parsing the stack map
+ // table without a full decoding (see below).
+ } else if ("StackMap".equals(attributeName)) {
+ if ((context.parsingOptions & SKIP_FRAMES) == 0) {
+ stackMapFrameOffset = currentOffset + 2;
+ stackMapTableEndOffset = currentOffset + attributeLength;
+ compressedFrames = false;
+ }
+ // IMPORTANT! Here we assume that the frames are ordered, as in the StackMapTable attribute,
+ // although this is not guaranteed by the attribute format. This allows an incremental
+ // extraction of the labels corresponding to this attribute (see the comment above for the
+ // StackMapTable attribute).
+ } else {
+ Attribute attribute =
+ readAttribute(
+ context.attributePrototypes,
+ attributeName,
+ currentOffset,
+ attributeLength,
+ charBuffer,
+ codeOffset,
+ labels);
+ attribute.nextAttribute = attributes;
+ attributes = attribute;
+ }
+ currentOffset += attributeLength;
+ }
+
+ // Initialize the context fields related to stack map frames, and generate the first
+ // (implicit) stack map frame, if needed.
+ final boolean expandFrames = (context.parsingOptions & EXPAND_FRAMES) != 0;
+ if (stackMapFrameOffset != 0) {
+ // The bytecode offset of the first explicit frame is not offset_delta + 1 but only
+ // offset_delta. Setting the implicit frame offset to -1 allows us to use of the
+ // "offset_delta + 1" rule in all cases.
+ context.currentFrameOffset = -1;
+ context.currentFrameType = 0;
+ context.currentFrameLocalCount = 0;
+ context.currentFrameLocalCountDelta = 0;
+ context.currentFrameLocalTypes = new Object[maxLocals];
+ context.currentFrameStackCount = 0;
+ context.currentFrameStackTypes = new Object[maxStack];
+ if (expandFrames) {
+ computeImplicitFrame(context);
+ }
+ // Find the labels for UNINITIALIZED frame types. Instead of decoding each element of the
+ // stack map table, we look for 3 consecutive bytes that "look like" an UNINITIALIZED type
+ // (tag ITEM_Uninitialized, offset within bytecode bounds, NEW instruction at this offset).
+ // We may find false positives (i.e. not real UNINITIALIZED types), but this should be rare,
+ // and the only consequence will be the creation of an unneeded label. This is better than
+ // creating a label for each NEW instruction, and faster than fully decoding the whole stack
+ // map table.
+ for (int offset = stackMapFrameOffset; offset < stackMapTableEndOffset - 2; ++offset) {
+ if (classBuffer[offset] == Frame.ITEM_UNINITIALIZED) {
+ int potentialBytecodeOffset = readUnsignedShort(offset + 1);
+ if (potentialBytecodeOffset >= 0
+ && potentialBytecodeOffset < codeLength
+ && (classBuffer[bytecodeStartOffset + potentialBytecodeOffset] & 0xFF)
+ == Opcodes.NEW) {
+ createLabel(potentialBytecodeOffset, labels);
+ }
+ }
+ }
+ }
+ if (expandFrames && (context.parsingOptions & EXPAND_ASM_INSNS) != 0) {
+ // Expanding the ASM specific instructions can introduce F_INSERT frames, even if the method
+ // does not currently have any frame. These inserted frames must be computed by simulating the
+ // effect of the bytecode instructions, one by one, starting from the implicit first frame.
+ // For this, MethodWriter needs to know maxLocals before the first instruction is visited. To
+ // ensure this, we visit the implicit first frame here (passing only maxLocals - the rest is
+ // computed in MethodWriter).
+ methodVisitor.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+ }
+
+ // Visit the bytecode instructions. First, introduce state variables for the incremental parsing
+ // of the type annotations.
+
+ // Index of the next runtime visible type annotation to read (in the
+ // visibleTypeAnnotationOffsets array).
+ int currentVisibleTypeAnnotationIndex = 0;
+ // The bytecode offset of the next runtime visible type annotation to read, or -1.
+ int currentVisibleTypeAnnotationBytecodeOffset =
+ getTypeAnnotationBytecodeOffset(visibleTypeAnnotationOffsets, 0);
+ // Index of the next runtime invisible type annotation to read (in the
+ // invisibleTypeAnnotationOffsets array).
+ int currentInvisibleTypeAnnotationIndex = 0;
+ // The bytecode offset of the next runtime invisible type annotation to read, or -1.
+ int currentInvisibleTypeAnnotationBytecodeOffset =
+ getTypeAnnotationBytecodeOffset(invisibleTypeAnnotationOffsets, 0);
+
+ // Whether a F_INSERT stack map frame must be inserted before the current instruction.
+ boolean insertFrame = false;
+
+ // The delta to subtract from a goto_w or jsr_w opcode to get the corresponding goto or jsr
+ // opcode, or 0 if goto_w and jsr_w must be left unchanged (i.e. when expanding ASM specific
+ // instructions).
+ final int wideJumpOpcodeDelta =
+ (context.parsingOptions & EXPAND_ASM_INSNS) == 0 ? Constants.WIDE_JUMP_OPCODE_DELTA : 0;
+
+ currentOffset = bytecodeStartOffset;
+ while (currentOffset < bytecodeEndOffset) {
+ final int currentBytecodeOffset = currentOffset - bytecodeStartOffset;
+
+ // Visit the label and the line number(s) for this bytecode offset, if any.
+ Label currentLabel = labels[currentBytecodeOffset];
+ if (currentLabel != null) {
+ currentLabel.accept(methodVisitor, (context.parsingOptions & SKIP_DEBUG) == 0);
+ }
+
+ // Visit the stack map frame for this bytecode offset, if any.
+ while (stackMapFrameOffset != 0
+ && (context.currentFrameOffset == currentBytecodeOffset
+ || context.currentFrameOffset == -1)) {
+ // If there is a stack map frame for this offset, make methodVisitor visit it, and read the
+ // next stack map frame if there is one.
+ if (context.currentFrameOffset != -1) {
+ if (!compressedFrames || expandFrames) {
+ methodVisitor.visitFrame(
+ Opcodes.F_NEW,
+ context.currentFrameLocalCount,
+ context.currentFrameLocalTypes,
+ context.currentFrameStackCount,
+ context.currentFrameStackTypes);
+ } else {
+ methodVisitor.visitFrame(
+ context.currentFrameType,
+ context.currentFrameLocalCountDelta,
+ context.currentFrameLocalTypes,
+ context.currentFrameStackCount,
+ context.currentFrameStackTypes);
+ }
+ // Since there is already a stack map frame for this bytecode offset, there is no need to
+ // insert a new one.
+ insertFrame = false;
+ }
+ if (stackMapFrameOffset < stackMapTableEndOffset) {
+ stackMapFrameOffset =
+ readStackMapFrame(stackMapFrameOffset, compressedFrames, expandFrames, context);
+ } else {
+ stackMapFrameOffset = 0;
+ }
+ }
+
+ // Insert a stack map frame for this bytecode offset, if requested by setting insertFrame to
+ // true during the previous iteration. The actual frame content is computed in MethodWriter.
+ if (insertFrame) {
+ if ((context.parsingOptions & EXPAND_FRAMES) != 0) {
+ methodVisitor.visitFrame(Constants.F_INSERT, 0, null, 0, null);
+ }
+ insertFrame = false;
+ }
+
+ // Visit the instruction at this bytecode offset.
+ int opcode = classBuffer[currentOffset] & 0xFF;
+ switch (opcode) {
+ case Opcodes.NOP:
+ case Opcodes.ACONST_NULL:
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.IALOAD:
+ case Opcodes.LALOAD:
+ case Opcodes.FALOAD:
+ case Opcodes.DALOAD:
+ case Opcodes.AALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IASTORE:
+ case Opcodes.LASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.DASTORE:
+ case Opcodes.AASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.POP:
+ case Opcodes.POP2:
+ case Opcodes.DUP:
+ case Opcodes.DUP_X1:
+ case Opcodes.DUP_X2:
+ case Opcodes.DUP2:
+ case Opcodes.DUP2_X1:
+ case Opcodes.DUP2_X2:
+ case Opcodes.SWAP:
+ case Opcodes.IADD:
+ case Opcodes.LADD:
+ case Opcodes.FADD:
+ case Opcodes.DADD:
+ case Opcodes.ISUB:
+ case Opcodes.LSUB:
+ case Opcodes.FSUB:
+ case Opcodes.DSUB:
+ case Opcodes.IMUL:
+ case Opcodes.LMUL:
+ case Opcodes.FMUL:
+ case Opcodes.DMUL:
+ case Opcodes.IDIV:
+ case Opcodes.LDIV:
+ case Opcodes.FDIV:
+ case Opcodes.DDIV:
+ case Opcodes.IREM:
+ case Opcodes.LREM:
+ case Opcodes.FREM:
+ case Opcodes.DREM:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.ISHL:
+ case Opcodes.LSHL:
+ case Opcodes.ISHR:
+ case Opcodes.LSHR:
+ case Opcodes.IUSHR:
+ case Opcodes.LUSHR:
+ case Opcodes.IAND:
+ case Opcodes.LAND:
+ case Opcodes.IOR:
+ case Opcodes.LOR:
+ case Opcodes.IXOR:
+ case Opcodes.LXOR:
+ case Opcodes.I2L:
+ case Opcodes.I2F:
+ case Opcodes.I2D:
+ case Opcodes.L2I:
+ case Opcodes.L2F:
+ case Opcodes.L2D:
+ case Opcodes.F2I:
+ case Opcodes.F2L:
+ case Opcodes.F2D:
+ case Opcodes.D2I:
+ case Opcodes.D2L:
+ case Opcodes.D2F:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.LCMP:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.RETURN:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ methodVisitor.visitInsn(opcode);
+ currentOffset += 1;
+ break;
+ case Constants.ILOAD_0:
+ case Constants.ILOAD_1:
+ case Constants.ILOAD_2:
+ case Constants.ILOAD_3:
+ case Constants.LLOAD_0:
+ case Constants.LLOAD_1:
+ case Constants.LLOAD_2:
+ case Constants.LLOAD_3:
+ case Constants.FLOAD_0:
+ case Constants.FLOAD_1:
+ case Constants.FLOAD_2:
+ case Constants.FLOAD_3:
+ case Constants.DLOAD_0:
+ case Constants.DLOAD_1:
+ case Constants.DLOAD_2:
+ case Constants.DLOAD_3:
+ case Constants.ALOAD_0:
+ case Constants.ALOAD_1:
+ case Constants.ALOAD_2:
+ case Constants.ALOAD_3:
+ opcode -= Constants.ILOAD_0;
+ methodVisitor.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
+ currentOffset += 1;
+ break;
+ case Constants.ISTORE_0:
+ case Constants.ISTORE_1:
+ case Constants.ISTORE_2:
+ case Constants.ISTORE_3:
+ case Constants.LSTORE_0:
+ case Constants.LSTORE_1:
+ case Constants.LSTORE_2:
+ case Constants.LSTORE_3:
+ case Constants.FSTORE_0:
+ case Constants.FSTORE_1:
+ case Constants.FSTORE_2:
+ case Constants.FSTORE_3:
+ case Constants.DSTORE_0:
+ case Constants.DSTORE_1:
+ case Constants.DSTORE_2:
+ case Constants.DSTORE_3:
+ case Constants.ASTORE_0:
+ case Constants.ASTORE_1:
+ case Constants.ASTORE_2:
+ case Constants.ASTORE_3:
+ opcode -= Constants.ISTORE_0;
+ methodVisitor.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), opcode & 0x3);
+ currentOffset += 1;
+ break;
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.GOTO:
+ case Opcodes.JSR:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ methodVisitor.visitJumpInsn(
+ opcode, labels[currentBytecodeOffset + readShort(currentOffset + 1)]);
+ currentOffset += 3;
+ break;
+ case Constants.GOTO_W:
+ case Constants.JSR_W:
+ methodVisitor.visitJumpInsn(
+ opcode - wideJumpOpcodeDelta,
+ labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
+ currentOffset += 5;
+ break;
+ case Constants.ASM_IFEQ:
+ case Constants.ASM_IFNE:
+ case Constants.ASM_IFLT:
+ case Constants.ASM_IFGE:
+ case Constants.ASM_IFGT:
+ case Constants.ASM_IFLE:
+ case Constants.ASM_IF_ICMPEQ:
+ case Constants.ASM_IF_ICMPNE:
+ case Constants.ASM_IF_ICMPLT:
+ case Constants.ASM_IF_ICMPGE:
+ case Constants.ASM_IF_ICMPGT:
+ case Constants.ASM_IF_ICMPLE:
+ case Constants.ASM_IF_ACMPEQ:
+ case Constants.ASM_IF_ACMPNE:
+ case Constants.ASM_GOTO:
+ case Constants.ASM_JSR:
+ case Constants.ASM_IFNULL:
+ case Constants.ASM_IFNONNULL:
+ {
+ // A forward jump with an offset > 32767. In this case we automatically replace ASM_GOTO
+ // with GOTO_W, ASM_JSR with JSR_W and ASM_IFxxx <l> with IFNOTxxx <L> GOTO_W <l> L:...,
+ // where IFNOTxxx is the "opposite" opcode of ASMS_IFxxx (e.g. IFNE for ASM_IFEQ) and
+ // where <L> designates the instruction just after the GOTO_W.
+ // First, change the ASM specific opcodes ASM_IFEQ ... ASM_JSR, ASM_IFNULL and
+ // ASM_IFNONNULL to IFEQ ... JSR, IFNULL and IFNONNULL.
+ opcode =
+ opcode < Constants.ASM_IFNULL
+ ? opcode - Constants.ASM_OPCODE_DELTA
+ : opcode - Constants.ASM_IFNULL_OPCODE_DELTA;
+ Label target = labels[currentBytecodeOffset + readUnsignedShort(currentOffset + 1)];
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ // Replace GOTO with GOTO_W and JSR with JSR_W.
+ methodVisitor.visitJumpInsn(opcode + Constants.WIDE_JUMP_OPCODE_DELTA, target);
+ } else {
+ // Compute the "opposite" of opcode. This can be done by flipping the least
+ // significant bit for IFNULL and IFNONNULL, and similarly for IFEQ ... IF_ACMPEQ
+ // (with a pre and post offset by 1).
+ opcode = opcode < Opcodes.GOTO ? ((opcode + 1) ^ 1) - 1 : opcode ^ 1;
+ Label endif = createLabel(currentBytecodeOffset + 3, labels);
+ methodVisitor.visitJumpInsn(opcode, endif);
+ methodVisitor.visitJumpInsn(Constants.GOTO_W, target);
+ // endif designates the instruction just after GOTO_W, and is visited as part of the
+ // next instruction. Since it is a jump target, we need to insert a frame here.
+ insertFrame = true;
+ }
+ currentOffset += 3;
+ break;
+ }
+ case Constants.ASM_GOTO_W:
+ // Replace ASM_GOTO_W with GOTO_W.
+ methodVisitor.visitJumpInsn(
+ Constants.GOTO_W, labels[currentBytecodeOffset + readInt(currentOffset + 1)]);
+ // The instruction just after is a jump target (because ASM_GOTO_W is used in patterns
+ // IFNOTxxx <L> ASM_GOTO_W <l> L:..., see MethodWriter), so we need to insert a frame
+ // here.
+ insertFrame = true;
+ currentOffset += 5;
+ break;
+ case Constants.WIDE:
+ opcode = classBuffer[currentOffset + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ methodVisitor.visitIincInsn(
+ readUnsignedShort(currentOffset + 2), readShort(currentOffset + 4));
+ currentOffset += 6;
+ } else {
+ methodVisitor.visitVarInsn(opcode, readUnsignedShort(currentOffset + 2));
+ currentOffset += 4;
+ }
+ break;
+ case Opcodes.TABLESWITCH:
+ {
+ // Skip 0 to 3 padding bytes.
+ currentOffset += 4 - (currentBytecodeOffset & 3);
+ // Read the instruction.
+ Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
+ int low = readInt(currentOffset + 4);
+ int high = readInt(currentOffset + 8);
+ currentOffset += 12;
+ Label[] table = new Label[high - low + 1];
+ for (int i = 0; i < table.length; ++i) {
+ table[i] = labels[currentBytecodeOffset + readInt(currentOffset)];
+ currentOffset += 4;
+ }
+ methodVisitor.visitTableSwitchInsn(low, high, defaultLabel, table);
+ break;
+ }
+ case Opcodes.LOOKUPSWITCH:
+ {
+ // Skip 0 to 3 padding bytes.
+ currentOffset += 4 - (currentBytecodeOffset & 3);
+ // Read the instruction.
+ Label defaultLabel = labels[currentBytecodeOffset + readInt(currentOffset)];
+ int numPairs = readInt(currentOffset + 4);
+ currentOffset += 8;
+ int[] keys = new int[numPairs];
+ Label[] values = new Label[numPairs];
+ for (int i = 0; i < numPairs; ++i) {
+ keys[i] = readInt(currentOffset);
+ values[i] = labels[currentBytecodeOffset + readInt(currentOffset + 4)];
+ currentOffset += 8;
+ }
+ methodVisitor.visitLookupSwitchInsn(defaultLabel, keys, values);
+ break;
+ }
+ case Opcodes.ILOAD:
+ case Opcodes.LLOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.DLOAD:
+ case Opcodes.ALOAD:
+ case Opcodes.ISTORE:
+ case Opcodes.LSTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.DSTORE:
+ case Opcodes.ASTORE:
+ case Opcodes.RET:
+ methodVisitor.visitVarInsn(opcode, classBuffer[currentOffset + 1] & 0xFF);
+ currentOffset += 2;
+ break;
+ case Opcodes.BIPUSH:
+ case Opcodes.NEWARRAY:
+ methodVisitor.visitIntInsn(opcode, classBuffer[currentOffset + 1]);
+ currentOffset += 2;
+ break;
+ case Opcodes.SIPUSH:
+ methodVisitor.visitIntInsn(opcode, readShort(currentOffset + 1));
+ currentOffset += 3;
+ break;
+ case Opcodes.LDC:
+ methodVisitor.visitLdcInsn(readConst(classBuffer[currentOffset + 1] & 0xFF, charBuffer));
+ currentOffset += 2;
+ break;
+ case Constants.LDC_W:
+ case Constants.LDC2_W:
+ methodVisitor.visitLdcInsn(readConst(readUnsignedShort(currentOffset + 1), charBuffer));
+ currentOffset += 3;
+ break;
+ case Opcodes.GETSTATIC:
+ case Opcodes.PUTSTATIC:
+ case Opcodes.GETFIELD:
+ case Opcodes.PUTFIELD:
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE:
+ {
+ int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
+ int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
+ String owner = readClass(cpInfoOffset, charBuffer);
+ String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
+ String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
+ if (opcode < Opcodes.INVOKEVIRTUAL) {
+ methodVisitor.visitFieldInsn(opcode, owner, name, descriptor);
+ } else {
+ boolean isInterface =
+ classBuffer[cpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
+ methodVisitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ if (opcode == Opcodes.INVOKEINTERFACE) {
+ currentOffset += 5;
+ } else {
+ currentOffset += 3;
+ }
+ break;
+ }
+ case Opcodes.INVOKEDYNAMIC:
+ {
+ int cpInfoOffset = cpInfoOffsets[readUnsignedShort(currentOffset + 1)];
+ int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
+ String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
+ String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
+ int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
+ Handle handle =
+ (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
+ Object[] bootstrapMethodArguments =
+ new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
+ bootstrapMethodOffset += 4;
+ for (int i = 0; i < bootstrapMethodArguments.length; i++) {
+ bootstrapMethodArguments[i] =
+ readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
+ bootstrapMethodOffset += 2;
+ }
+ methodVisitor.visitInvokeDynamicInsn(
+ name, descriptor, handle, bootstrapMethodArguments);
+ currentOffset += 5;
+ break;
+ }
+ case Opcodes.NEW:
+ case Opcodes.ANEWARRAY:
+ case Opcodes.CHECKCAST:
+ case Opcodes.INSTANCEOF:
+ methodVisitor.visitTypeInsn(opcode, readClass(currentOffset + 1, charBuffer));
+ currentOffset += 3;
+ break;
+ case Opcodes.IINC:
+ methodVisitor.visitIincInsn(
+ classBuffer[currentOffset + 1] & 0xFF, classBuffer[currentOffset + 2]);
+ currentOffset += 3;
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ methodVisitor.visitMultiANewArrayInsn(
+ readClass(currentOffset + 1, charBuffer), classBuffer[currentOffset + 3] & 0xFF);
+ currentOffset += 4;
+ break;
+ default:
+ throw new AssertionError();
+ }
+
+ // Visit the runtime visible instruction annotations, if any.
+ while (visibleTypeAnnotationOffsets != null
+ && currentVisibleTypeAnnotationIndex < visibleTypeAnnotationOffsets.length
+ && currentVisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
+ if (currentVisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
+ // Parse the target_type, target_info and target_path fields.
+ int currentAnnotationOffset =
+ readTypeAnnotationTarget(
+ context, visibleTypeAnnotationOffsets[currentVisibleTypeAnnotationIndex]);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ readElementValues(
+ methodVisitor.visitInsnAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ currentVisibleTypeAnnotationBytecodeOffset =
+ getTypeAnnotationBytecodeOffset(
+ visibleTypeAnnotationOffsets, ++currentVisibleTypeAnnotationIndex);
+ }
+
+ // Visit the runtime invisible instruction annotations, if any.
+ while (invisibleTypeAnnotationOffsets != null
+ && currentInvisibleTypeAnnotationIndex < invisibleTypeAnnotationOffsets.length
+ && currentInvisibleTypeAnnotationBytecodeOffset <= currentBytecodeOffset) {
+ if (currentInvisibleTypeAnnotationBytecodeOffset == currentBytecodeOffset) {
+ // Parse the target_type, target_info and target_path fields.
+ int currentAnnotationOffset =
+ readTypeAnnotationTarget(
+ context, invisibleTypeAnnotationOffsets[currentInvisibleTypeAnnotationIndex]);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer);
+ currentAnnotationOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ readElementValues(
+ methodVisitor.visitInsnAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentAnnotationOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ currentInvisibleTypeAnnotationBytecodeOffset =
+ getTypeAnnotationBytecodeOffset(
+ invisibleTypeAnnotationOffsets, ++currentInvisibleTypeAnnotationIndex);
+ }
+ }
+ if (labels[codeLength] != null) {
+ methodVisitor.visitLabel(labels[codeLength]);
+ }
+
+ // Visit LocalVariableTable and LocalVariableTypeTable attributes.
+ if (localVariableTableOffset != 0 && (context.parsingOptions & SKIP_DEBUG) == 0) {
+ // The (start_pc, index, signature_index) fields of each entry of the LocalVariableTypeTable.
+ int[] typeTable = null;
+ if (localVariableTypeTableOffset != 0) {
+ typeTable = new int[readUnsignedShort(localVariableTypeTableOffset) * 3];
+ currentOffset = localVariableTypeTableOffset + 2;
+ int typeTableIndex = typeTable.length;
+ while (typeTableIndex > 0) {
+ // Store the offset of 'signature_index', and the value of 'index' and 'start_pc'.
+ typeTable[--typeTableIndex] = currentOffset + 6;
+ typeTable[--typeTableIndex] = readUnsignedShort(currentOffset + 8);
+ typeTable[--typeTableIndex] = readUnsignedShort(currentOffset);
+ currentOffset += 10;
+ }
+ }
+ int localVariableTableLength = readUnsignedShort(localVariableTableOffset);
+ currentOffset = localVariableTableOffset + 2;
+ while (localVariableTableLength-- > 0) {
+ int startPc = readUnsignedShort(currentOffset);
+ int length = readUnsignedShort(currentOffset + 2);
+ String name = readUTF8(currentOffset + 4, charBuffer);
+ String descriptor = readUTF8(currentOffset + 6, charBuffer);
+ int index = readUnsignedShort(currentOffset + 8);
+ currentOffset += 10;
+ String signature = null;
+ if (typeTable != null) {
+ for (int i = 0; i < typeTable.length; i += 3) {
+ if (typeTable[i] == startPc && typeTable[i + 1] == index) {
+ signature = readUTF8(typeTable[i + 2], charBuffer);
+ break;
+ }
+ }
+ }
+ methodVisitor.visitLocalVariable(
+ name, descriptor, signature, labels[startPc], labels[startPc + length], index);
+ }
+ }
+
+ // Visit the local variable type annotations of the RuntimeVisibleTypeAnnotations attribute.
+ if (visibleTypeAnnotationOffsets != null) {
+ for (int typeAnnotationOffset : visibleTypeAnnotationOffsets) {
+ int targetType = readByte(typeAnnotationOffset);
+ if (targetType == TypeReference.LOCAL_VARIABLE
+ || targetType == TypeReference.RESOURCE_VARIABLE) {
+ // Parse the target_type, target_info and target_path fields.
+ currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentOffset, charBuffer);
+ currentOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ readElementValues(
+ methodVisitor.visitLocalVariableAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ context.currentLocalVariableAnnotationRangeStarts,
+ context.currentLocalVariableAnnotationRangeEnds,
+ context.currentLocalVariableAnnotationRangeIndices,
+ annotationDescriptor,
+ /* visible = */ true),
+ currentOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+ }
+
+ // Visit the local variable type annotations of the RuntimeInvisibleTypeAnnotations attribute.
+ if (invisibleTypeAnnotationOffsets != null) {
+ for (int typeAnnotationOffset : invisibleTypeAnnotationOffsets) {
+ int targetType = readByte(typeAnnotationOffset);
+ if (targetType == TypeReference.LOCAL_VARIABLE
+ || targetType == TypeReference.RESOURCE_VARIABLE) {
+ // Parse the target_type, target_info and target_path fields.
+ currentOffset = readTypeAnnotationTarget(context, typeAnnotationOffset);
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentOffset, charBuffer);
+ currentOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ readElementValues(
+ methodVisitor.visitLocalVariableAnnotation(
+ context.currentTypeAnnotationTarget,
+ context.currentTypeAnnotationTargetPath,
+ context.currentLocalVariableAnnotationRangeStarts,
+ context.currentLocalVariableAnnotationRangeEnds,
+ context.currentLocalVariableAnnotationRangeIndices,
+ annotationDescriptor,
+ /* visible = */ false),
+ currentOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+ }
+
+ // Visit the non standard attributes.
+ while (attributes != null) {
+ // Copy and reset the nextAttribute field so that it can also be used in MethodWriter.
+ Attribute nextAttribute = attributes.nextAttribute;
+ attributes.nextAttribute = null;
+ methodVisitor.visitAttribute(attributes);
+ attributes = nextAttribute;
+ }
+
+ // Visit the max stack and max locals values.
+ methodVisitor.visitMaxs(maxStack, maxLocals);
+ }
+
+ /**
+ * Returns the label corresponding to the given bytecode offset. The default implementation of
+ * this method creates a label for the given offset if it has not been already created.
+ *
+ * @param bytecodeOffset a bytecode offset in a method.
+ * @param labels the already created labels, indexed by their offset. If a label already exists
+ * for bytecodeOffset this method must not create a new one. Otherwise it must store the new
+ * label in this array.
+ * @return a non null Label, which must be equal to labels[bytecodeOffset].
+ */
+ protected Label readLabel(final int bytecodeOffset, final Label[] labels) {
+ if (labels[bytecodeOffset] == null) {
+ labels[bytecodeOffset] = new Label();
+ }
+ return labels[bytecodeOffset];
+ }
+
+ /**
+ * Creates a label without the {@link Label#FLAG_DEBUG_ONLY} flag set, for the given bytecode
+ * offset. The label is created with a call to {@link #readLabel} and its {@link
+ * Label#FLAG_DEBUG_ONLY} flag is cleared.
+ *
+ * @param bytecodeOffset a bytecode offset in a method.
+ * @param labels the already created labels, indexed by their offset.
+ * @return a Label without the {@link Label#FLAG_DEBUG_ONLY} flag set.
+ */
+ private Label createLabel(final int bytecodeOffset, final Label[] labels) {
+ Label label = readLabel(bytecodeOffset, labels);
+ label.flags &= ~Label.FLAG_DEBUG_ONLY;
+ return label;
+ }
+
+ /**
+ * Creates a label with the {@link Label#FLAG_DEBUG_ONLY} flag set, if there is no already
+ * existing label for the given bytecode offset (otherwise does nothing). The label is created
+ * with a call to {@link #readLabel}.
+ *
+ * @param bytecodeOffset a bytecode offset in a method.
+ * @param labels the already created labels, indexed by their offset.
+ */
+ private void createDebugLabel(final int bytecodeOffset, final Label[] labels) {
+ if (labels[bytecodeOffset] == null) {
+ readLabel(bytecodeOffset, labels).flags |= Label.FLAG_DEBUG_ONLY;
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Methods to parse annotations, type annotations and parameter annotations
+ // ----------------------------------------------------------------------------------------------
+
+ /**
+ * Parses a Runtime[In]VisibleTypeAnnotations attribute to find the offset of each type_annotation
+ * entry it contains, to find the corresponding labels, and to visit the try catch block
+ * annotations.
+ *
+ * @param methodVisitor the method visitor to be used to visit the try catch block annotations.
+ * @param context information about the class being parsed.
+ * @param runtimeTypeAnnotationsOffset the start offset of a Runtime[In]VisibleTypeAnnotations
+ * attribute, excluding the attribute_info's attribute_name_index and attribute_length fields.
+ * @param visible true if the attribute to parse is a RuntimeVisibleTypeAnnotations attribute,
+ * false it is a RuntimeInvisibleTypeAnnotations attribute.
+ * @return the start offset of each entry of the Runtime[In]VisibleTypeAnnotations_attribute's
+ * 'annotations' array field.
+ */
+ private int[] readTypeAnnotations(
+ final MethodVisitor methodVisitor,
+ final Context context,
+ final int runtimeTypeAnnotationsOffset,
+ final boolean visible) {
+ char[] charBuffer = context.charBuffer;
+ int currentOffset = runtimeTypeAnnotationsOffset;
+ // Read the num_annotations field and create an array to store the type_annotation offsets.
+ int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)];
+ currentOffset += 2;
+ // Parse the 'annotations' array field.
+ for (int i = 0; i < typeAnnotationsOffsets.length; ++i) {
+ typeAnnotationsOffsets[i] = currentOffset;
+ // Parse the type_annotation's target_type and the target_info fields. The size of the
+ // target_info field depends on the value of target_type.
+ int targetType = readInt(currentOffset);
+ switch (targetType >>> 24) {
+ case TypeReference.LOCAL_VARIABLE:
+ case TypeReference.RESOURCE_VARIABLE:
+ // A localvar_target has a variable size, which depends on the value of their table_length
+ // field. It also references bytecode offsets, for which we need labels.
+ int tableLength = readUnsignedShort(currentOffset + 1);
+ currentOffset += 3;
+ while (tableLength-- > 0) {
+ int startPc = readUnsignedShort(currentOffset);
+ int length = readUnsignedShort(currentOffset + 2);
+ // Skip the index field (2 bytes).
+ currentOffset += 6;
+ createLabel(startPc, context.currentMethodLabels);
+ createLabel(startPc + length, context.currentMethodLabels);
+ }
+ break;
+ case TypeReference.CAST:
+ case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+ currentOffset += 4;
+ break;
+ case TypeReference.CLASS_EXTENDS:
+ case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+ case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+ case TypeReference.THROWS:
+ case TypeReference.EXCEPTION_PARAMETER:
+ case TypeReference.INSTANCEOF:
+ case TypeReference.NEW:
+ case TypeReference.CONSTRUCTOR_REFERENCE:
+ case TypeReference.METHOD_REFERENCE:
+ currentOffset += 3;
+ break;
+ case TypeReference.CLASS_TYPE_PARAMETER:
+ case TypeReference.METHOD_TYPE_PARAMETER:
+ case TypeReference.METHOD_FORMAL_PARAMETER:
+ case TypeReference.FIELD:
+ case TypeReference.METHOD_RETURN:
+ case TypeReference.METHOD_RECEIVER:
+ default:
+ // TypeReference type which can't be used in Code attribute, or which is unknown.
+ throw new IllegalArgumentException();
+ }
+ // Parse the rest of the type_annotation structure, starting with the target_path structure
+ // (whose size depends on its path_length field).
+ int pathLength = readByte(currentOffset);
+ if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) {
+ // Parse the target_path structure and create a corresponding TypePath.
+ TypePath path = pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
+ currentOffset += 1 + 2 * pathLength;
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentOffset, charBuffer);
+ currentOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentOffset =
+ readElementValues(
+ methodVisitor.visitTryCatchAnnotation(
+ targetType & 0xFFFFFF00, path, annotationDescriptor, visible),
+ currentOffset,
+ /* named = */ true,
+ charBuffer);
+ } else {
+ // We don't want to visit the other target_type annotations, so we just skip them (which
+ // requires some parsing because the element_value_pairs array has a variable size). First,
+ // skip the target_path structure:
+ currentOffset += 3 + 2 * pathLength;
+ // Then skip the num_element_value_pairs and element_value_pairs fields (by reading them
+ // with a null AnnotationVisitor).
+ currentOffset =
+ readElementValues(
+ /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
+ }
+ }
+ return typeAnnotationsOffsets;
+ }
+
+ /**
+ * Returns the bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or
+ * -1 if there is no such type_annotation of if it does not have a bytecode offset.
+ *
+ * @param typeAnnotationOffsets the offset of each 'type_annotation' entry in a
+ * Runtime[In]VisibleTypeAnnotations attribute, or {@literal null}.
+ * @param typeAnnotationIndex the index a 'type_annotation' entry in typeAnnotationOffsets.
+ * @return bytecode offset corresponding to the specified JVMS 'type_annotation' structure, or -1
+ * if there is no such type_annotation of if it does not have a bytecode offset.
+ */
+ private int getTypeAnnotationBytecodeOffset(
+ final int[] typeAnnotationOffsets, final int typeAnnotationIndex) {
+ if (typeAnnotationOffsets == null
+ || typeAnnotationIndex >= typeAnnotationOffsets.length
+ || readByte(typeAnnotationOffsets[typeAnnotationIndex]) < TypeReference.INSTANCEOF) {
+ return -1;
+ }
+ return readUnsignedShort(typeAnnotationOffsets[typeAnnotationIndex] + 1);
+ }
+
+ /**
+ * Parses the header of a JVMS type_annotation structure to extract its target_type, target_info
+ * and target_path (the result is stored in the given context), and returns the start offset of
+ * the rest of the type_annotation structure.
+ *
+ * @param context information about the class being parsed. This is where the extracted
+ * target_type and target_path must be stored.
+ * @param typeAnnotationOffset the start offset of a type_annotation structure.
+ * @return the start offset of the rest of the type_annotation structure.
+ */
+ private int readTypeAnnotationTarget(final Context context, final int typeAnnotationOffset) {
+ int currentOffset = typeAnnotationOffset;
+ // Parse and store the target_type structure.
+ int targetType = readInt(typeAnnotationOffset);
+ switch (targetType >>> 24) {
+ case TypeReference.CLASS_TYPE_PARAMETER:
+ case TypeReference.METHOD_TYPE_PARAMETER:
+ case TypeReference.METHOD_FORMAL_PARAMETER:
+ targetType &= 0xFFFF0000;
+ currentOffset += 2;
+ break;
+ case TypeReference.FIELD:
+ case TypeReference.METHOD_RETURN:
+ case TypeReference.METHOD_RECEIVER:
+ targetType &= 0xFF000000;
+ currentOffset += 1;
+ break;
+ case TypeReference.LOCAL_VARIABLE:
+ case TypeReference.RESOURCE_VARIABLE:
+ targetType &= 0xFF000000;
+ int tableLength = readUnsignedShort(currentOffset + 1);
+ currentOffset += 3;
+ context.currentLocalVariableAnnotationRangeStarts = new Label[tableLength];
+ context.currentLocalVariableAnnotationRangeEnds = new Label[tableLength];
+ context.currentLocalVariableAnnotationRangeIndices = new int[tableLength];
+ for (int i = 0; i < tableLength; ++i) {
+ int startPc = readUnsignedShort(currentOffset);
+ int length = readUnsignedShort(currentOffset + 2);
+ int index = readUnsignedShort(currentOffset + 4);
+ currentOffset += 6;
+ context.currentLocalVariableAnnotationRangeStarts[i] =
+ createLabel(startPc, context.currentMethodLabels);
+ context.currentLocalVariableAnnotationRangeEnds[i] =
+ createLabel(startPc + length, context.currentMethodLabels);
+ context.currentLocalVariableAnnotationRangeIndices[i] = index;
+ }
+ break;
+ case TypeReference.CAST:
+ case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT:
+ case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT:
+ targetType &= 0xFF0000FF;
+ currentOffset += 4;
+ break;
+ case TypeReference.CLASS_EXTENDS:
+ case TypeReference.CLASS_TYPE_PARAMETER_BOUND:
+ case TypeReference.METHOD_TYPE_PARAMETER_BOUND:
+ case TypeReference.THROWS:
+ case TypeReference.EXCEPTION_PARAMETER:
+ targetType &= 0xFFFFFF00;
+ currentOffset += 3;
+ break;
+ case TypeReference.INSTANCEOF:
+ case TypeReference.NEW:
+ case TypeReference.CONSTRUCTOR_REFERENCE:
+ case TypeReference.METHOD_REFERENCE:
+ targetType &= 0xFF000000;
+ currentOffset += 3;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ context.currentTypeAnnotationTarget = targetType;
+ // Parse and store the target_path structure.
+ int pathLength = readByte(currentOffset);
+ context.currentTypeAnnotationTargetPath =
+ pathLength == 0 ? null : new TypePath(classFileBuffer, currentOffset);
+ // Return the start offset of the rest of the type_annotation structure.
+ return currentOffset + 1 + 2 * pathLength;
+ }
+
+ /**
+ * Reads a Runtime[In]VisibleParameterAnnotations attribute and makes the given visitor visit it.
+ *
+ * @param methodVisitor the visitor that must visit the parameter annotations.
+ * @param context information about the class being parsed.
+ * @param runtimeParameterAnnotationsOffset the start offset of a
+ * Runtime[In]VisibleParameterAnnotations attribute, excluding the attribute_info's
+ * attribute_name_index and attribute_length fields.
+ * @param visible true if the attribute to parse is a RuntimeVisibleParameterAnnotations
+ * attribute, false it is a RuntimeInvisibleParameterAnnotations attribute.
+ */
+ private void readParameterAnnotations(
+ final MethodVisitor methodVisitor,
+ final Context context,
+ final int runtimeParameterAnnotationsOffset,
+ final boolean visible) {
+ int currentOffset = runtimeParameterAnnotationsOffset;
+ int numParameters = classFileBuffer[currentOffset++] & 0xFF;
+ methodVisitor.visitAnnotableParameterCount(numParameters, visible);
+ char[] charBuffer = context.charBuffer;
+ for (int i = 0; i < numParameters; ++i) {
+ int numAnnotations = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (numAnnotations-- > 0) {
+ // Parse the type_index field.
+ String annotationDescriptor = readUTF8(currentOffset, charBuffer);
+ currentOffset += 2;
+ // Parse num_element_value_pairs and element_value_pairs and visit these values.
+ currentOffset =
+ readElementValues(
+ methodVisitor.visitParameterAnnotation(i, annotationDescriptor, visible),
+ currentOffset,
+ /* named = */ true,
+ charBuffer);
+ }
+ }
+ }
+
+ /**
+ * Reads the element values of a JVMS 'annotation' structure and makes the given visitor visit
+ * them. This method can also be used to read the values of the JVMS 'array_value' field of an
+ * annotation's 'element_value'.
+ *
+ * @param annotationVisitor the visitor that must visit the values.
+ * @param annotationOffset the start offset of an 'annotation' structure (excluding its type_index
+ * field) or of an 'array_value' structure.
+ * @param named if the annotation values are named or not. This should be true to parse the values
+ * of a JVMS 'annotation' structure, and false to parse the JVMS 'array_value' of an
+ * annotation's element_value.
+ * @param charBuffer the buffer used to read strings in the constant pool.
+ * @return the end offset of the JVMS 'annotation' or 'array_value' structure.
+ */
+ private int readElementValues(
+ final AnnotationVisitor annotationVisitor,
+ final int annotationOffset,
+ final boolean named,
+ final char[] charBuffer) {
+ int currentOffset = annotationOffset;
+ // Read the num_element_value_pairs field (or num_values field for an array_value).
+ int numElementValuePairs = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ if (named) {
+ // Parse the element_value_pairs array.
+ while (numElementValuePairs-- > 0) {
+ String elementName = readUTF8(currentOffset, charBuffer);
+ currentOffset =
+ readElementValue(annotationVisitor, currentOffset + 2, elementName, charBuffer);
+ }
+ } else {
+ // Parse the array_value array.
+ while (numElementValuePairs-- > 0) {
+ currentOffset =
+ readElementValue(annotationVisitor, currentOffset, /* elementName= */ null, charBuffer);
+ }
+ }
+ if (annotationVisitor != null) {
+ annotationVisitor.visitEnd();
+ }
+ return currentOffset;
+ }
+
+ /**
+ * Reads a JVMS 'element_value' structure and makes the given visitor visit it.
+ *
+ * @param annotationVisitor the visitor that must visit the element_value structure.
+ * @param elementValueOffset the start offset in {@link #classFileBuffer} of the element_value
+ * structure to be read.
+ * @param elementName the name of the element_value structure to be read, or {@literal null}.
+ * @param charBuffer the buffer used to read strings in the constant pool.
+ * @return the end offset of the JVMS 'element_value' structure.
+ */
+ private int readElementValue(
+ final AnnotationVisitor annotationVisitor,
+ final int elementValueOffset,
+ final String elementName,
+ final char[] charBuffer) {
+ int currentOffset = elementValueOffset;
+ if (annotationVisitor == null) {
+ switch (classFileBuffer[currentOffset] & 0xFF) {
+ case 'e': // enum_const_value
+ return currentOffset + 5;
+ case '@': // annotation_value
+ return readElementValues(null, currentOffset + 3, /* named = */ true, charBuffer);
+ case '[': // array_value
+ return readElementValues(null, currentOffset + 1, /* named = */ false, charBuffer);
+ default:
+ return currentOffset + 3;
+ }
+ }
+ switch (classFileBuffer[currentOffset++] & 0xFF) {
+ case 'B': // const_value_index, CONSTANT_Integer
+ annotationVisitor.visit(
+ elementName, (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
+ currentOffset += 2;
+ break;
+ case 'C': // const_value_index, CONSTANT_Integer
+ annotationVisitor.visit(
+ elementName, (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
+ currentOffset += 2;
+ break;
+ case 'D': // const_value_index, CONSTANT_Double
+ case 'F': // const_value_index, CONSTANT_Float
+ case 'I': // const_value_index, CONSTANT_Integer
+ case 'J': // const_value_index, CONSTANT_Long
+ annotationVisitor.visit(
+ elementName, readConst(readUnsignedShort(currentOffset), charBuffer));
+ currentOffset += 2;
+ break;
+ case 'S': // const_value_index, CONSTANT_Integer
+ annotationVisitor.visit(
+ elementName, (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]));
+ currentOffset += 2;
+ break;
+
+ case 'Z': // const_value_index, CONSTANT_Integer
+ annotationVisitor.visit(
+ elementName,
+ readInt(cpInfoOffsets[readUnsignedShort(currentOffset)]) == 0
+ ? Boolean.FALSE
+ : Boolean.TRUE);
+ currentOffset += 2;
+ break;
+ case 's': // const_value_index, CONSTANT_Utf8
+ annotationVisitor.visit(elementName, readUTF8(currentOffset, charBuffer));
+ currentOffset += 2;
+ break;
+ case 'e': // enum_const_value
+ annotationVisitor.visitEnum(
+ elementName,
+ readUTF8(currentOffset, charBuffer),
+ readUTF8(currentOffset + 2, charBuffer));
+ currentOffset += 4;
+ break;
+ case 'c': // class_info
+ annotationVisitor.visit(elementName, Type.getType(readUTF8(currentOffset, charBuffer)));
+ currentOffset += 2;
+ break;
+ case '@': // annotation_value
+ currentOffset =
+ readElementValues(
+ annotationVisitor.visitAnnotation(elementName, readUTF8(currentOffset, charBuffer)),
+ currentOffset + 2,
+ true,
+ charBuffer);
+ break;
+ case '[': // array_value
+ int numValues = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ if (numValues == 0) {
+ return readElementValues(
+ annotationVisitor.visitArray(elementName),
+ currentOffset - 2,
+ /* named = */ false,
+ charBuffer);
+ }
+ switch (classFileBuffer[currentOffset] & 0xFF) {
+ case 'B':
+ byte[] byteValues = new byte[numValues];
+ for (int i = 0; i < numValues; i++) {
+ byteValues[i] = (byte) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, byteValues);
+ break;
+ case 'Z':
+ boolean[] booleanValues = new boolean[numValues];
+ for (int i = 0; i < numValues; i++) {
+ booleanValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]) != 0;
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, booleanValues);
+ break;
+ case 'S':
+ short[] shortValues = new short[numValues];
+ for (int i = 0; i < numValues; i++) {
+ shortValues[i] = (short) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, shortValues);
+ break;
+ case 'C':
+ char[] charValues = new char[numValues];
+ for (int i = 0; i < numValues; i++) {
+ charValues[i] = (char) readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, charValues);
+ break;
+ case 'I':
+ int[] intValues = new int[numValues];
+ for (int i = 0; i < numValues; i++) {
+ intValues[i] = readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, intValues);
+ break;
+ case 'J':
+ long[] longValues = new long[numValues];
+ for (int i = 0; i < numValues; i++) {
+ longValues[i] = readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]);
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, longValues);
+ break;
+ case 'F':
+ float[] floatValues = new float[numValues];
+ for (int i = 0; i < numValues; i++) {
+ floatValues[i] =
+ Float.intBitsToFloat(
+ readInt(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, floatValues);
+ break;
+ case 'D':
+ double[] doubleValues = new double[numValues];
+ for (int i = 0; i < numValues; i++) {
+ doubleValues[i] =
+ Double.longBitsToDouble(
+ readLong(cpInfoOffsets[readUnsignedShort(currentOffset + 1)]));
+ currentOffset += 3;
+ }
+ annotationVisitor.visit(elementName, doubleValues);
+ break;
+ default:
+ currentOffset =
+ readElementValues(
+ annotationVisitor.visitArray(elementName),
+ currentOffset - 2,
+ /* named = */ false,
+ charBuffer);
+ break;
+ }
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ return currentOffset;
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Methods to parse stack map frames
+ // ----------------------------------------------------------------------------------------------
+
+ /**
+ * Computes the implicit frame of the method currently being parsed (as defined in the given
+ * {@link Context}) and stores it in the given context.
+ *
+ * @param context information about the class being parsed.
+ */
+ private void computeImplicitFrame(final Context context) {
+ String methodDescriptor = context.currentMethodDescriptor;
+ Object[] locals = context.currentFrameLocalTypes;
+ int numLocal = 0;
+ if ((context.currentMethodAccessFlags & Opcodes.ACC_STATIC) == 0) {
+ if ("<init>".equals(context.currentMethodName)) {
+ locals[numLocal++] = Opcodes.UNINITIALIZED_THIS;
+ } else {
+ locals[numLocal++] = readClass(header + 2, context.charBuffer);
+ }
+ }
+ // Parse the method descriptor, one argument type descriptor at each iteration. Start by
+ // skipping the first method descriptor character, which is always '('.
+ int currentMethodDescritorOffset = 1;
+ while (true) {
+ int currentArgumentDescriptorStartOffset = currentMethodDescritorOffset;
+ switch (methodDescriptor.charAt(currentMethodDescritorOffset++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ locals[numLocal++] = Opcodes.INTEGER;
+ break;
+ case 'F':
+ locals[numLocal++] = Opcodes.FLOAT;
+ break;
+ case 'J':
+ locals[numLocal++] = Opcodes.LONG;
+ break;
+ case 'D':
+ locals[numLocal++] = Opcodes.DOUBLE;
+ break;
+ case '[':
+ while (methodDescriptor.charAt(currentMethodDescritorOffset) == '[') {
+ ++currentMethodDescritorOffset;
+ }
+ if (methodDescriptor.charAt(currentMethodDescritorOffset) == 'L') {
+ ++currentMethodDescritorOffset;
+ while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
+ ++currentMethodDescritorOffset;
+ }
+ }
+ locals[numLocal++] =
+ methodDescriptor.substring(
+ currentArgumentDescriptorStartOffset, ++currentMethodDescritorOffset);
+ break;
+ case 'L':
+ while (methodDescriptor.charAt(currentMethodDescritorOffset) != ';') {
+ ++currentMethodDescritorOffset;
+ }
+ locals[numLocal++] =
+ methodDescriptor.substring(
+ currentArgumentDescriptorStartOffset + 1, currentMethodDescritorOffset++);
+ break;
+ default:
+ context.currentFrameLocalCount = numLocal;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Reads a JVMS 'stack_map_frame' structure and stores the result in the given {@link Context}
+ * object. This method can also be used to read a full_frame structure, excluding its frame_type
+ * field (this is used to parse the legacy StackMap attributes).
+ *
+ * @param stackMapFrameOffset the start offset in {@link #classFileBuffer} of the
+ * stack_map_frame_value structure to be read, or the start offset of a full_frame structure
+ * (excluding its frame_type field).
+ * @param compressed true to read a 'stack_map_frame' structure, false to read a 'full_frame'
+ * structure without its frame_type field.
+ * @param expand if the stack map frame must be expanded. See {@link #EXPAND_FRAMES}.
+ * @param context where the parsed stack map frame must be stored.
+ * @return the end offset of the JVMS 'stack_map_frame' or 'full_frame' structure.
+ */
+ private int readStackMapFrame(
+ final int stackMapFrameOffset,
+ final boolean compressed,
+ final boolean expand,
+ final Context context) {
+ int currentOffset = stackMapFrameOffset;
+ final char[] charBuffer = context.charBuffer;
+ final Label[] labels = context.currentMethodLabels;
+ int frameType;
+ if (compressed) {
+ // Read the frame_type field.
+ frameType = classFileBuffer[currentOffset++] & 0xFF;
+ } else {
+ frameType = Frame.FULL_FRAME;
+ context.currentFrameOffset = -1;
+ }
+ int offsetDelta;
+ context.currentFrameLocalCountDelta = 0;
+ if (frameType < Frame.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+ offsetDelta = frameType;
+ context.currentFrameType = Opcodes.F_SAME;
+ context.currentFrameStackCount = 0;
+ } else if (frameType < Frame.RESERVED) {
+ offsetDelta = frameType - Frame.SAME_LOCALS_1_STACK_ITEM_FRAME;
+ currentOffset =
+ readVerificationTypeInfo(
+ currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
+ context.currentFrameType = Opcodes.F_SAME1;
+ context.currentFrameStackCount = 1;
+ } else if (frameType >= Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+ offsetDelta = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ if (frameType == Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+ currentOffset =
+ readVerificationTypeInfo(
+ currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels);
+ context.currentFrameType = Opcodes.F_SAME1;
+ context.currentFrameStackCount = 1;
+ } else if (frameType >= Frame.CHOP_FRAME && frameType < Frame.SAME_FRAME_EXTENDED) {
+ context.currentFrameType = Opcodes.F_CHOP;
+ context.currentFrameLocalCountDelta = Frame.SAME_FRAME_EXTENDED - frameType;
+ context.currentFrameLocalCount -= context.currentFrameLocalCountDelta;
+ context.currentFrameStackCount = 0;
+ } else if (frameType == Frame.SAME_FRAME_EXTENDED) {
+ context.currentFrameType = Opcodes.F_SAME;
+ context.currentFrameStackCount = 0;
+ } else if (frameType < Frame.FULL_FRAME) {
+ int local = expand ? context.currentFrameLocalCount : 0;
+ for (int k = frameType - Frame.SAME_FRAME_EXTENDED; k > 0; k--) {
+ currentOffset =
+ readVerificationTypeInfo(
+ currentOffset, context.currentFrameLocalTypes, local++, charBuffer, labels);
+ }
+ context.currentFrameType = Opcodes.F_APPEND;
+ context.currentFrameLocalCountDelta = frameType - Frame.SAME_FRAME_EXTENDED;
+ context.currentFrameLocalCount += context.currentFrameLocalCountDelta;
+ context.currentFrameStackCount = 0;
+ } else {
+ final int numberOfLocals = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ context.currentFrameType = Opcodes.F_FULL;
+ context.currentFrameLocalCountDelta = numberOfLocals;
+ context.currentFrameLocalCount = numberOfLocals;
+ for (int local = 0; local < numberOfLocals; ++local) {
+ currentOffset =
+ readVerificationTypeInfo(
+ currentOffset, context.currentFrameLocalTypes, local, charBuffer, labels);
+ }
+ final int numberOfStackItems = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ context.currentFrameStackCount = numberOfStackItems;
+ for (int stack = 0; stack < numberOfStackItems; ++stack) {
+ currentOffset =
+ readVerificationTypeInfo(
+ currentOffset, context.currentFrameStackTypes, stack, charBuffer, labels);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException();
+ }
+ context.currentFrameOffset += offsetDelta + 1;
+ createLabel(context.currentFrameOffset, labels);
+ return currentOffset;
+ }
+
+ /**
+ * Reads a JVMS 'verification_type_info' structure and stores it at the given index in the given
+ * array.
+ *
+ * @param verificationTypeInfoOffset the start offset of the 'verification_type_info' structure to
+ * read.
+ * @param frame the array where the parsed type must be stored.
+ * @param index the index in 'frame' where the parsed type must be stored.
+ * @param charBuffer the buffer used to read strings in the constant pool.
+ * @param labels the labels of the method currently being parsed, indexed by their offset. If the
+ * parsed type is an ITEM_Uninitialized, a new label for the corresponding NEW instruction is
+ * stored in this array if it does not already exist.
+ * @return the end offset of the JVMS 'verification_type_info' structure.
+ */
+ private int readVerificationTypeInfo(
+ final int verificationTypeInfoOffset,
+ final Object[] frame,
+ final int index,
+ final char[] charBuffer,
+ final Label[] labels) {
+ int currentOffset = verificationTypeInfoOffset;
+ int tag = classFileBuffer[currentOffset++] & 0xFF;
+ switch (tag) {
+ case Frame.ITEM_TOP:
+ frame[index] = Opcodes.TOP;
+ break;
+ case Frame.ITEM_INTEGER:
+ frame[index] = Opcodes.INTEGER;
+ break;
+ case Frame.ITEM_FLOAT:
+ frame[index] = Opcodes.FLOAT;
+ break;
+ case Frame.ITEM_DOUBLE:
+ frame[index] = Opcodes.DOUBLE;
+ break;
+ case Frame.ITEM_LONG:
+ frame[index] = Opcodes.LONG;
+ break;
+ case Frame.ITEM_NULL:
+ frame[index] = Opcodes.NULL;
+ break;
+ case Frame.ITEM_UNINITIALIZED_THIS:
+ frame[index] = Opcodes.UNINITIALIZED_THIS;
+ break;
+ case Frame.ITEM_OBJECT:
+ frame[index] = readClass(currentOffset, charBuffer);
+ currentOffset += 2;
+ break;
+ case Frame.ITEM_UNINITIALIZED:
+ frame[index] = createLabel(readUnsignedShort(currentOffset), labels);
+ currentOffset += 2;
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ return currentOffset;
+ }
+
+ // ----------------------------------------------------------------------------------------------
+ // Methods to parse attributes
+ // ----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
+ * field entry.
+ *
+ * @return the offset in {@link #classFileBuffer} of the first ClassFile's 'attributes' array
+ * field entry.
+ */
+ final int getFirstAttributeOffset() {
+ // Skip the access_flags, this_class, super_class, and interfaces_count fields (using 2 bytes
+ // each), as well as the interfaces array field (2 bytes per interface).
+ int currentOffset = header + 8 + readUnsignedShort(header + 6) * 2;
+
+ // Read the fields_count field.
+ int fieldsCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ // Skip the 'fields' array field.
+ while (fieldsCount-- > 0) {
+ // Invariant: currentOffset is the offset of a field_info structure.
+ // Skip the access_flags, name_index and descriptor_index fields (2 bytes each), and read the
+ // attributes_count field.
+ int attributesCount = readUnsignedShort(currentOffset + 6);
+ currentOffset += 8;
+ // Skip the 'attributes' array field.
+ while (attributesCount-- > 0) {
+ // Invariant: currentOffset is the offset of an attribute_info structure.
+ // Read the attribute_length field (2 bytes after the start of the attribute_info) and skip
+ // this many bytes, plus 6 for the attribute_name_index and attribute_length fields
+ // (yielding the total size of the attribute_info structure).
+ currentOffset += 6 + readInt(currentOffset + 2);
+ }
+ }
+
+ // Skip the methods_count and 'methods' fields, using the same method as above.
+ int methodsCount = readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ while (methodsCount-- > 0) {
+ int attributesCount = readUnsignedShort(currentOffset + 6);
+ currentOffset += 8;
+ while (attributesCount-- > 0) {
+ currentOffset += 6 + readInt(currentOffset + 2);
+ }
+ }
+
+ // Skip the ClassFile's attributes_count field.
+ return currentOffset + 2;
+ }
+
+ /**
+ * Reads the BootstrapMethods attribute to compute the offset of each bootstrap method.
+ *
+ * @param maxStringLength a conservative estimate of the maximum length of the strings contained
+ * in the constant pool of the class.
+ * @return the offsets of the bootstrap methods.
+ */
+ private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
+ char[] charBuffer = new char[maxStringLength];
+ int currentAttributeOffset = getFirstAttributeOffset();
+ for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
+ // Read the attribute_info's attribute_name and attribute_length fields.
+ String attributeName = readUTF8(currentAttributeOffset, charBuffer);
+ int attributeLength = readInt(currentAttributeOffset + 2);
+ currentAttributeOffset += 6;
+ if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
+ // Read the num_bootstrap_methods field and create an array of this size.
+ int[] result = new int[readUnsignedShort(currentAttributeOffset)];
+ // Compute and store the offset of each 'bootstrap_methods' array field entry.
+ int currentBootstrapMethodOffset = currentAttributeOffset + 2;
+ for (int j = 0; j < result.length; ++j) {
+ result[j] = currentBootstrapMethodOffset;
+ // Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
+ // as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
+ currentBootstrapMethodOffset +=
+ 4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
+ }
+ return result;
+ }
+ currentAttributeOffset += attributeLength;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Reads a non standard JVMS 'attribute' structure in {@link #classFileBuffer}.
+ *
+ * @param attributePrototypes prototypes of the attributes that must be parsed during the visit of
+ * the class. Any attribute whose type is not equal to the type of one the prototypes will not
+ * be parsed: its byte array value will be passed unchanged to the ClassWriter.
+ * @param type the type of the attribute.
+ * @param offset the start offset of the JVMS 'attribute' structure in {@link #classFileBuffer}.
+ * The 6 attribute header bytes (attribute_name_index and attribute_length) are not taken into
+ * account here.
+ * @param length the length of the attribute's content (excluding the 6 attribute header bytes).
+ * @param charBuffer the buffer to be used to read strings in the constant pool.
+ * @param codeAttributeOffset the start offset of the enclosing Code attribute in {@link
+ * #classFileBuffer}, or -1 if the attribute to be read is not a code attribute. The 6
+ * attribute header bytes (attribute_name_index and attribute_length) are not taken into
+ * account here.
+ * @param labels the labels of the method's code, or {@literal null} if the attribute to be read
+ * is not a code attribute.
+ * @return the attribute that has been read.
+ */
+ private Attribute readAttribute(
+ final Attribute[] attributePrototypes,
+ final String type,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ for (Attribute attributePrototype : attributePrototypes) {
+ if (attributePrototype.type.equals(type)) {
+ return attributePrototype.read(
+ this, offset, length, charBuffer, codeAttributeOffset, labels);
+ }
+ }
+ return new Attribute(type).read(this, offset, length, null, -1, null);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods: low level parsing
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the number of entries in the class's constant pool table.
+ *
+ * @return the number of entries in the class's constant pool table.
+ */
+ public int getItemCount() {
+ return cpInfoOffsets.length;
+ }
+
+ /**
+ * Returns the start offset in this {@link ClassReader} of a JVMS 'cp_info' structure (i.e. a
+ * constant pool entry), plus one. <i>This method is intended for {@link Attribute} sub classes,
+ * and is normally not needed by class generators or adapters.</i>
+ *
+ * @param constantPoolEntryIndex the index a constant pool entry in the class's constant pool
+ * table.
+ * @return the start offset in this {@link ClassReader} of the corresponding JVMS 'cp_info'
+ * structure, plus one.
+ */
+ public int getItem(final int constantPoolEntryIndex) {
+ return cpInfoOffsets[constantPoolEntryIndex];
+ }
+
+ /**
+ * Returns a conservative estimate of the maximum length of the strings contained in the class's
+ * constant pool table.
+ *
+ * @return a conservative estimate of the maximum length of the strings contained in the class's
+ * constant pool table.
+ */
+ public int getMaxStringLength() {
+ return maxStringLength;
+ }
+
+ /**
+ * Reads a byte value in this {@link ClassReader}. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param offset the start offset of the value to be read in this {@link ClassReader}.
+ * @return the read value.
+ */
+ public int readByte(final int offset) {
+ return classFileBuffer[offset] & 0xFF;
+ }
+
+ /**
+ * Reads an unsigned short value in this {@link ClassReader}. <i>This method is intended for
+ * {@link Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param offset the start index of the value to be read in this {@link ClassReader}.
+ * @return the read value.
+ */
+ public int readUnsignedShort(final int offset) {
+ byte[] classBuffer = classFileBuffer;
+ return ((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF);
+ }
+
+ /**
+ * Reads a signed short value in this {@link ClassReader}. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param offset the start offset of the value to be read in this {@link ClassReader}.
+ * @return the read value.
+ */
+ public short readShort(final int offset) {
+ byte[] classBuffer = classFileBuffer;
+ return (short) (((classBuffer[offset] & 0xFF) << 8) | (classBuffer[offset + 1] & 0xFF));
+ }
+
+ /**
+ * Reads a signed int value in this {@link ClassReader}. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param offset the start offset of the value to be read in this {@link ClassReader}.
+ * @return the read value.
+ */
+ public int readInt(final int offset) {
+ byte[] classBuffer = classFileBuffer;
+ return ((classBuffer[offset] & 0xFF) << 24)
+ | ((classBuffer[offset + 1] & 0xFF) << 16)
+ | ((classBuffer[offset + 2] & 0xFF) << 8)
+ | (classBuffer[offset + 3] & 0xFF);
+ }
+
+ /**
+ * Reads a signed long value in this {@link ClassReader}. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param offset the start offset of the value to be read in this {@link ClassReader}.
+ * @return the read value.
+ */
+ public long readLong(final int offset) {
+ long l1 = readInt(offset);
+ long l0 = readInt(offset + 4) & 0xFFFFFFFFL;
+ return (l1 << 32) | l0;
+ }
+
+ /**
+ * Reads a CONSTANT_Utf8 constant pool entry in this {@link ClassReader}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
+ * value is the index of a CONSTANT_Utf8 entry in the class's constant pool table.
+ * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified CONSTANT_Utf8 entry.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ public String readUTF8(final int offset, final char[] charBuffer) {
+ int constantPoolEntryIndex = readUnsignedShort(offset);
+ if (offset == 0 || constantPoolEntryIndex == 0) {
+ return null;
+ }
+ return readUtf(constantPoolEntryIndex, charBuffer);
+ }
+
+ /**
+ * Reads a CONSTANT_Utf8 constant pool entry in {@link #classFileBuffer}.
+ *
+ * @param constantPoolEntryIndex the index of a CONSTANT_Utf8 entry in the class's constant pool
+ * table.
+ * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified CONSTANT_Utf8 entry.
+ */
+ final String readUtf(final int constantPoolEntryIndex, final char[] charBuffer) {
+ String value = constantUtf8Values[constantPoolEntryIndex];
+ if (value != null) {
+ return value;
+ }
+ int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
+ return constantUtf8Values[constantPoolEntryIndex] =
+ readUtf(cpInfoOffset + 2, readUnsignedShort(cpInfoOffset), charBuffer);
+ }
+
+ /**
+ * Reads an UTF8 string in {@link #classFileBuffer}.
+ *
+ * @param utfOffset the start offset of the UTF8 string to be read.
+ * @param utfLength the length of the UTF8 string to be read.
+ * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified UTF8 string.
+ */
+ private String readUtf(final int utfOffset, final int utfLength, final char[] charBuffer) {
+ int currentOffset = utfOffset;
+ int endOffset = currentOffset + utfLength;
+ int strLength = 0;
+ byte[] classBuffer = classFileBuffer;
+ while (currentOffset < endOffset) {
+ int currentByte = classBuffer[currentOffset++];
+ if ((currentByte & 0x80) == 0) {
+ charBuffer[strLength++] = (char) (currentByte & 0x7F);
+ } else if ((currentByte & 0xE0) == 0xC0) {
+ charBuffer[strLength++] =
+ (char) (((currentByte & 0x1F) << 6) + (classBuffer[currentOffset++] & 0x3F));
+ } else {
+ charBuffer[strLength++] =
+ (char)
+ (((currentByte & 0xF) << 12)
+ + ((classBuffer[currentOffset++] & 0x3F) << 6)
+ + (classBuffer[currentOffset++] & 0x3F));
+ }
+ }
+ return new String(charBuffer, 0, strLength);
+ }
+
+ /**
+ * Reads a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType, CONSTANT_Module or
+ * CONSTANT_Package constant pool entry in {@link #classFileBuffer}. <i>This method is intended
+ * for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param offset the start offset of an unsigned short value in {@link #classFileBuffer}, whose
+ * value is the index of a CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
+ * CONSTANT_Module or CONSTANT_Package entry in class's constant pool table.
+ * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified constant pool entry.
+ */
+ private String readStringish(final int offset, final char[] charBuffer) {
+ // Get the start offset of the cp_info structure (plus one), and read the CONSTANT_Utf8 entry
+ // designated by the first two bytes of this cp_info.
+ return readUTF8(cpInfoOffsets[readUnsignedShort(offset)], charBuffer);
+ }
+
+ /**
+ * Reads a CONSTANT_Class constant pool entry in this {@link ClassReader}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
+ * value is the index of a CONSTANT_Class entry in class's constant pool table.
+ * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified CONSTANT_Class entry.
+ */
+ public String readClass(final int offset, final char[] charBuffer) {
+ return readStringish(offset, charBuffer);
+ }
+
+ /**
+ * Reads a CONSTANT_Module constant pool entry in this {@link ClassReader}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
+ * value is the index of a CONSTANT_Module entry in class's constant pool table.
+ * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified CONSTANT_Module entry.
+ */
+ public String readModule(final int offset, final char[] charBuffer) {
+ return readStringish(offset, charBuffer);
+ }
+
+ /**
+ * Reads a CONSTANT_Package constant pool entry in this {@link ClassReader}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param offset the start offset of an unsigned short value in this {@link ClassReader}, whose
+ * value is the index of a CONSTANT_Package entry in class's constant pool table.
+ * @param charBuffer the buffer to be used to read the item. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the String corresponding to the specified CONSTANT_Package entry.
+ */
+ public String readPackage(final int offset, final char[] charBuffer) {
+ return readStringish(offset, charBuffer);
+ }
+
+ /**
+ * Reads a CONSTANT_Dynamic constant pool entry in {@link #classFileBuffer}.
+ *
+ * @param constantPoolEntryIndex the index of a CONSTANT_Dynamic entry in the class's constant
+ * pool table.
+ * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the ConstantDynamic corresponding to the specified CONSTANT_Dynamic entry.
+ */
+ private ConstantDynamic readConstantDynamic(
+ final int constantPoolEntryIndex, final char[] charBuffer) {
+ ConstantDynamic constantDynamic = constantDynamicValues[constantPoolEntryIndex];
+ if (constantDynamic != null) {
+ return constantDynamic;
+ }
+ int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
+ int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)];
+ String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
+ String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
+ int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)];
+ Handle handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
+ Object[] bootstrapMethodArguments = new Object[readUnsignedShort(bootstrapMethodOffset + 2)];
+ bootstrapMethodOffset += 4;
+ for (int i = 0; i < bootstrapMethodArguments.length; i++) {
+ bootstrapMethodArguments[i] = readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer);
+ bootstrapMethodOffset += 2;
+ }
+ return constantDynamicValues[constantPoolEntryIndex] =
+ new ConstantDynamic(name, descriptor, handle, bootstrapMethodArguments);
+ }
+
+ /**
+ * Reads a numeric or string constant pool entry in this {@link ClassReader}. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by class generators or
+ * adapters.</i>
+ *
+ * @param constantPoolEntryIndex the index of a CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
+ * CONSTANT_Double, CONSTANT_Class, CONSTANT_String, CONSTANT_MethodType,
+ * CONSTANT_MethodHandle or CONSTANT_Dynamic entry in the class's constant pool.
+ * @param charBuffer the buffer to be used to read strings. This buffer must be sufficiently
+ * large. It is not automatically resized.
+ * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
+ * {@link Type}, {@link Handle} or {@link ConstantDynamic} corresponding to the specified
+ * constant pool entry.
+ */
+ public Object readConst(final int constantPoolEntryIndex, final char[] charBuffer) {
+ int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex];
+ switch (classFileBuffer[cpInfoOffset - 1]) {
+ case Symbol.CONSTANT_INTEGER_TAG:
+ return readInt(cpInfoOffset);
+ case Symbol.CONSTANT_FLOAT_TAG:
+ return Float.intBitsToFloat(readInt(cpInfoOffset));
+ case Symbol.CONSTANT_LONG_TAG:
+ return readLong(cpInfoOffset);
+ case Symbol.CONSTANT_DOUBLE_TAG:
+ return Double.longBitsToDouble(readLong(cpInfoOffset));
+ case Symbol.CONSTANT_CLASS_TAG:
+ return Type.getObjectType(readUTF8(cpInfoOffset, charBuffer));
+ case Symbol.CONSTANT_STRING_TAG:
+ return readUTF8(cpInfoOffset, charBuffer);
+ case Symbol.CONSTANT_METHOD_TYPE_TAG:
+ return Type.getMethodType(readUTF8(cpInfoOffset, charBuffer));
+ case Symbol.CONSTANT_METHOD_HANDLE_TAG:
+ int referenceKind = readByte(cpInfoOffset);
+ int referenceCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 1)];
+ int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(referenceCpInfoOffset + 2)];
+ String owner = readClass(referenceCpInfoOffset, charBuffer);
+ String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer);
+ String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer);
+ boolean isInterface =
+ classFileBuffer[referenceCpInfoOffset - 1] == Symbol.CONSTANT_INTERFACE_METHODREF_TAG;
+ return new Handle(referenceKind, owner, name, descriptor, isInterface);
+ case Symbol.CONSTANT_DYNAMIC_TAG:
+ return readConstantDynamic(constantPoolEntryIndex, charBuffer);
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ClassTooLargeException.java b/asm/src/main/java/org/objectweb/asm/ClassTooLargeException.java
new file mode 100644
index 00000000..de177b1e
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ClassTooLargeException.java
@@ -0,0 +1,72 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * Exception thrown when the constant pool of a class produced by a {@link ClassWriter} is too
+ * large.
+ *
+ * @author Jason Zaugg
+ */
+public final class ClassTooLargeException extends IndexOutOfBoundsException {
+ private static final long serialVersionUID = 160715609518896765L;
+
+ private final String className;
+ private final int constantPoolCount;
+
+ /**
+ * Constructs a new {@link ClassTooLargeException}.
+ *
+ * @param className the internal name of the class (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ * @param constantPoolCount the number of constant pool items of the class.
+ */
+ public ClassTooLargeException(final String className, final int constantPoolCount) {
+ super("Class too large: " + className);
+ this.className = className;
+ this.constantPoolCount = constantPoolCount;
+ }
+
+ /**
+ * Returns the internal name of the class (see {@link org.objectweb.asm.Type#getInternalName()}).
+ *
+ * @return the internal name of the class.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Returns the number of constant pool items of the class.
+ *
+ * @return the number of constant pool items of the class.
+ */
+ public int getConstantPoolCount() {
+ return constantPoolCount;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ClassVisitor.java b/asm/src/main/java/org/objectweb/asm/ClassVisitor.java
new file mode 100644
index 00000000..b4cba80b
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ClassVisitor.java
@@ -0,0 +1,398 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java class. The methods of this class must be called in the following order:
+ * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code
+ * visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code
+ * visitAttribute} )* ( {@code visitNestMember} | [ {@code * visitPermittedSubclass} ] | {@code
+ * visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )*
+ * {@code visitEnd}.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class ClassVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /** The class visitor to which this visitor must delegate method calls. May be {@literal null}. */
+ protected ClassVisitor cv;
+
+ /**
+ * Constructs a new {@link ClassVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected ClassVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ClassVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param classVisitor the class visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ protected ClassVisitor(final int api, final ClassVisitor classVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.cv = classVisitor;
+ }
+
+ /**
+ * The class visitor to which this visitor must delegate method calls. May be {@literal null}.
+ *
+ * @return the class visitor to which this visitor must delegate method calls, or {@literal null}.
+ */
+ public ClassVisitor getDelegate() {
+ return cv;
+ }
+
+ /**
+ * Visits the header of the class.
+ *
+ * @param version the class version. The minor version is stored in the 16 most significant bits,
+ * and the major version in the 16 least significant bits.
+ * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the class is deprecated {@link Opcodes#ACC_DEPRECATED} or a record {@link
+ * Opcodes#ACC_RECORD}.
+ * @param name the internal name of the class (see {@link Type#getInternalName()}).
+ * @param signature the signature of this class. May be {@literal null} if the class is not a
+ * generic one, and does not extend or implement generic classes or interfaces.
+ * @param superName the internal of name of the super class (see {@link Type#getInternalName()}).
+ * For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the
+ * {@link Object} class.
+ * @param interfaces the internal names of the class's interfaces (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ */
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if (api < Opcodes.ASM8 && (access & Opcodes.ACC_RECORD) != 0) {
+ throw new UnsupportedOperationException("Records requires ASM8");
+ }
+ if (cv != null) {
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+ }
+
+ /**
+ * Visits the source of the class.
+ *
+ * @param source the name of the source file from which the class was compiled. May be {@literal
+ * null}.
+ * @param debug additional debug information to compute the correspondence between source and
+ * compiled elements of the class. May be {@literal null}.
+ */
+ public void visitSource(final String source, final String debug) {
+ if (cv != null) {
+ cv.visitSource(source, debug);
+ }
+ }
+
+ /**
+ * Visit the module corresponding to the class.
+ *
+ * @param name the fully qualified name (using dots) of the module.
+ * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+ * ACC_MANDATED}.
+ * @param version the module version, or {@literal null}.
+ * @return a visitor to visit the module values, or {@literal null} if this visitor is not
+ * interested in visiting this module.
+ */
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ if (api < Opcodes.ASM6) {
+ throw new UnsupportedOperationException("Module requires ASM6");
+ }
+ if (cv != null) {
+ return cv.visitModule(name, access, version);
+ }
+ return null;
+ }
+
+ /**
+ * Visits the nest host class of the class. A nest is a set of classes of the same package that
+ * share access to their private members. One of these classes, called the host, lists the other
+ * members of the nest, which in turn should link to the host of their nest. This method must be
+ * called only once and only if the visited class is a non-host member of a nest. A class is
+ * implicitly its own nest, so it's invalid to call this method with the visited class name as
+ * argument.
+ *
+ * @param nestHost the internal name of the host class of the nest (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitNestHost(final String nestHost) {
+ if (api < Opcodes.ASM7) {
+ throw new UnsupportedOperationException("NestHost requires ASM7");
+ }
+ if (cv != null) {
+ cv.visitNestHost(nestHost);
+ }
+ }
+
+ /**
+ * Visits the enclosing class of the class. This method must be called only if this class is a
+ * local or anonymous class. See the JVMS 4.7.7 section for more details.
+ *
+ * @param owner internal name of the enclosing class of the class (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the method that contains the class, or {@literal null} if the class is
+ * not enclosed in a method or constructor of its enclosing class (e.g. if it is enclosed in
+ * an instance initializer, static initializer, instance variable initializer, or class
+ * variable initializer).
+ * @param descriptor the descriptor of the method that contains the class, or {@literal null} if
+ * the class is not enclosed in a method or constructor of its enclosing class (e.g. if it is
+ * enclosed in an instance initializer, static initializer, instance variable initializer, or
+ * class variable initializer).
+ */
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ if (cv != null) {
+ cv.visitOuterClass(owner, name, descriptor);
+ }
+ }
+
+ /**
+ * Visits an annotation of the class.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (cv != null) {
+ return cv.visitAnnotation(descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on a type in the class signature.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
+ * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException("TypeAnnotation requires ASM5");
+ }
+ if (cv != null) {
+ return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a non standard attribute of the class.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ if (cv != null) {
+ cv.visitAttribute(attribute);
+ }
+ }
+
+ /**
+ * Visits a member of the nest. A nest is a set of classes of the same package that share access
+ * to their private members. One of these classes, called the host, lists the other members of the
+ * nest, which in turn should link to the host of their nest. This method must be called only if
+ * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so
+ * it's invalid to call this method with the visited class name as argument.
+ *
+ * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}).
+ */
+ public void visitNestMember(final String nestMember) {
+ if (api < Opcodes.ASM7) {
+ throw new UnsupportedOperationException("NestMember requires ASM7");
+ }
+ if (cv != null) {
+ cv.visitNestMember(nestMember);
+ }
+ }
+
+ /**
+ * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the
+ * current class.
+ *
+ * @param permittedSubclass the internal name of a permitted subclass (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitPermittedSubclass(final String permittedSubclass) {
+ if (api < Opcodes.ASM9) {
+ throw new UnsupportedOperationException("PermittedSubclasses requires ASM9");
+ }
+ if (cv != null) {
+ cv.visitPermittedSubclass(permittedSubclass);
+ }
+ }
+
+ /**
+ * Visits information about an inner class. This inner class is not necessarily a member of the
+ * class being visited. More precisely, every class or interface C which is referenced by this
+ * class and which is not a package member must be visited with this method. This class must
+ * reference its nested class or interface members, and its enclosing class, if any. See the JVMS
+ * 4.7.6 section for more details.
+ *
+ * @param name the internal name of C (see {@link Type#getInternalName()}).
+ * @param outerName the internal name of the class or interface C is a member of (see {@link
+ * Type#getInternalName()}). Must be {@literal null} if C is not the member of a class or
+ * interface (e.g. for local or anonymous classes).
+ * @param innerName the (simple) name of C. Must be {@literal null} for anonymous inner classes.
+ * @param access the access flags of C originally declared in the source code from which this
+ * class was compiled.
+ */
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ if (cv != null) {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+ }
+
+ /**
+ * Visits a record component of the class.
+ *
+ * @param name the record component name.
+ * @param descriptor the record component descriptor (see {@link Type}).
+ * @param signature the record component signature. May be {@literal null} if the record component
+ * type does not use generic types.
+ * @return a visitor to visit this record component annotations and attributes, or {@literal null}
+ * if this class visitor is not interested in visiting these annotations and attributes.
+ */
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ if (api < Opcodes.ASM8) {
+ throw new UnsupportedOperationException("Record requires ASM8");
+ }
+ if (cv != null) {
+ return cv.visitRecordComponent(name, descriptor, signature);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a field of the class.
+ *
+ * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the field is synthetic and/or deprecated.
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link Type}).
+ * @param signature the field's signature. May be {@literal null} if the field's type does not use
+ * generic types.
+ * @param value the field's initial value. This parameter, which may be {@literal null} if the
+ * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
+ * Long}, a {@link Double} or a {@link String} (for {@code int}, {@code float}, {@code long}
+ * or {@code String} fields respectively). <i>This parameter is only used for static
+ * fields</i>. Its value is ignored for non static fields, which must be initialized through
+ * bytecode instructions in constructors or methods.
+ * @return a visitor to visit field annotations and attributes, or {@literal null} if this class
+ * visitor is not interested in visiting these annotations and attributes.
+ */
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ if (cv != null) {
+ return cv.visitField(access, name, descriptor, signature, value);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor}
+ * instance (or {@literal null}) each time it is called, i.e., it should not return a previously
+ * returned visitor.
+ *
+ * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
+ * the method is synthetic and/or deprecated.
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param signature the method's signature. May be {@literal null} if the method parameters,
+ * return type and exceptions do not use generic types.
+ * @param exceptions the internal names of the method's exception classes (see {@link
+ * Type#getInternalName()}). May be {@literal null}.
+ * @return an object to visit the byte code of the method, or {@literal null} if this class
+ * visitor is not interested in visiting the code of this method.
+ */
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ if (cv != null) {
+ return cv.visitMethod(access, name, descriptor, signature, exceptions);
+ }
+ return null;
+ }
+
+ /**
+ * Visits the end of the class. This method, which is the last one to be called, is used to inform
+ * the visitor that all the fields and methods of the class have been visited.
+ */
+ public void visitEnd() {
+ if (cv != null) {
+ cv.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ClassWriter.java b/asm/src/main/java/org/objectweb/asm/ClassWriter.java
new file mode 100644
index 00000000..078efa20
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ClassWriter.java
@@ -0,0 +1,1079 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A {@link ClassVisitor} that generates a corresponding ClassFile structure, as defined in the Java
+ * Virtual Machine Specification (JVMS). It can be used alone, to generate a Java class "from
+ * scratch", or with one or more {@link ClassReader} and adapter {@link ClassVisitor} to generate a
+ * modified class from one or more existing Java classes.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html">JVMS 4</a>
+ * @author Eric Bruneton
+ */
+public class ClassWriter extends ClassVisitor {
+
+ /**
+ * A flag to automatically compute the maximum stack size and the maximum number of local
+ * variables of methods. If this flag is set, then the arguments of the {@link
+ * MethodVisitor#visitMaxs} method of the {@link MethodVisitor} returned by the {@link
+ * #visitMethod} method will be ignored, and computed automatically from the signature and the
+ * bytecode of each method.
+ *
+ * <p><b>Note:</b> for classes whose version is {@link Opcodes#V1_7} of more, this option requires
+ * valid stack map frames. The maximum stack size is then computed from these frames, and from the
+ * bytecode instructions in between. If stack map frames are not present or must be recomputed,
+ * used {@link #COMPUTE_FRAMES} instead.
+ *
+ * @see #ClassWriter(int)
+ */
+ public static final int COMPUTE_MAXS = 1;
+
+ /**
+ * A flag to automatically compute the stack map frames of methods from scratch. If this flag is
+ * set, then the calls to the {@link MethodVisitor#visitFrame} method are ignored, and the stack
+ * map frames are recomputed from the methods bytecode. The arguments of the {@link
+ * MethodVisitor#visitMaxs} method are also ignored and recomputed from the bytecode. In other
+ * words, {@link #COMPUTE_FRAMES} implies {@link #COMPUTE_MAXS}.
+ *
+ * @see #ClassWriter(int)
+ */
+ public static final int COMPUTE_FRAMES = 2;
+
+ /**
+ * The flags passed to the constructor. Must be zero or more of {@link #COMPUTE_MAXS} and {@link
+ * #COMPUTE_FRAMES}.
+ */
+ private final int flags;
+
+ // Note: fields are ordered as in the ClassFile structure, and those related to attributes are
+ // ordered as in Section 4.7 of the JVMS.
+
+ /**
+ * The minor_version and major_version fields of the JVMS ClassFile structure. minor_version is
+ * stored in the 16 most significant bits, and major_version in the 16 least significant bits.
+ */
+ private int version;
+
+ /** The symbol table for this class (contains the constant_pool and the BootstrapMethods). */
+ private final SymbolTable symbolTable;
+
+ /**
+ * The access_flags field of the JVMS ClassFile structure. This field can contain ASM specific
+ * access flags, such as {@link Opcodes#ACC_DEPRECATED} or {@link Opcodes#ACC_RECORD}, which are
+ * removed when generating the ClassFile structure.
+ */
+ private int accessFlags;
+
+ /** The this_class field of the JVMS ClassFile structure. */
+ private int thisClass;
+
+ /** The super_class field of the JVMS ClassFile structure. */
+ private int superClass;
+
+ /** The interface_count field of the JVMS ClassFile structure. */
+ private int interfaceCount;
+
+ /** The 'interfaces' array of the JVMS ClassFile structure. */
+ private int[] interfaces;
+
+ /**
+ * The fields of this class, stored in a linked list of {@link FieldWriter} linked via their
+ * {@link FieldWriter#fv} field. This field stores the first element of this list.
+ */
+ private FieldWriter firstField;
+
+ /**
+ * The fields of this class, stored in a linked list of {@link FieldWriter} linked via their
+ * {@link FieldWriter#fv} field. This field stores the last element of this list.
+ */
+ private FieldWriter lastField;
+
+ /**
+ * The methods of this class, stored in a linked list of {@link MethodWriter} linked via their
+ * {@link MethodWriter#mv} field. This field stores the first element of this list.
+ */
+ private MethodWriter firstMethod;
+
+ /**
+ * The methods of this class, stored in a linked list of {@link MethodWriter} linked via their
+ * {@link MethodWriter#mv} field. This field stores the last element of this list.
+ */
+ private MethodWriter lastMethod;
+
+ /** The number_of_classes field of the InnerClasses attribute, or 0. */
+ private int numberOfInnerClasses;
+
+ /** The 'classes' array of the InnerClasses attribute, or {@literal null}. */
+ private ByteVector innerClasses;
+
+ /** The class_index field of the EnclosingMethod attribute, or 0. */
+ private int enclosingClassIndex;
+
+ /** The method_index field of the EnclosingMethod attribute. */
+ private int enclosingMethodIndex;
+
+ /** The signature_index field of the Signature attribute, or 0. */
+ private int signatureIndex;
+
+ /** The source_file_index field of the SourceFile attribute, or 0. */
+ private int sourceFileIndex;
+
+ /** The debug_extension field of the SourceDebugExtension attribute, or {@literal null}. */
+ private ByteVector debugExtension;
+
+ /**
+ * The last runtime visible annotation of this class. The previous ones can be accessed with the
+ * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleAnnotation;
+
+ /**
+ * The last runtime invisible annotation of this class. The previous ones can be accessed with the
+ * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleAnnotation;
+
+ /**
+ * The last runtime visible type annotation of this class. The previous ones can be accessed with
+ * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
+
+ /**
+ * The last runtime invisible type annotation of this class. The previous ones can be accessed
+ * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
+
+ /** The Module attribute of this class, or {@literal null}. */
+ private ModuleWriter moduleWriter;
+
+ /** The host_class_index field of the NestHost attribute, or 0. */
+ private int nestHostClassIndex;
+
+ /** The number_of_classes field of the NestMembers attribute, or 0. */
+ private int numberOfNestMemberClasses;
+
+ /** The 'classes' array of the NestMembers attribute, or {@literal null}. */
+ private ByteVector nestMemberClasses;
+
+ /** The number_of_classes field of the PermittedSubclasses attribute, or 0. */
+ private int numberOfPermittedSubclasses;
+
+ /** The 'classes' array of the PermittedSubclasses attribute, or {@literal null}. */
+ private ByteVector permittedSubclasses;
+
+ /**
+ * The record components of this class, stored in a linked list of {@link RecordComponentWriter}
+ * linked via their {@link RecordComponentWriter#delegate} field. This field stores the first
+ * element of this list.
+ */
+ private RecordComponentWriter firstRecordComponent;
+
+ /**
+ * The record components of this class, stored in a linked list of {@link RecordComponentWriter}
+ * linked via their {@link RecordComponentWriter#delegate} field. This field stores the last
+ * element of this list.
+ */
+ private RecordComponentWriter lastRecordComponent;
+
+ /**
+ * The first non standard attribute of this class. The next ones can be accessed with the {@link
+ * Attribute#nextAttribute} field. May be {@literal null}.
+ *
+ * <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
+ * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
+ * #toByteArray} method writes the attributes in the order defined by this list, i.e. in the
+ * reverse order specified by the user.
+ */
+ private Attribute firstAttribute;
+
+ /**
+ * Indicates what must be automatically computed in {@link MethodWriter}. Must be one of {@link
+ * MethodWriter#COMPUTE_NOTHING}, {@link MethodWriter#COMPUTE_MAX_STACK_AND_LOCAL}, {@link
+ * MethodWriter#COMPUTE_INSERTED_FRAMES}, or {@link MethodWriter#COMPUTE_ALL_FRAMES}.
+ */
+ private int compute;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link ClassWriter} object.
+ *
+ * @param flags option flags that can be used to modify the default behavior of this class. Must
+ * be zero or more of {@link #COMPUTE_MAXS} and {@link #COMPUTE_FRAMES}.
+ */
+ public ClassWriter(final int flags) {
+ this(null, flags);
+ }
+
+ /**
+ * Constructs a new {@link ClassWriter} object and enables optimizations for "mostly add" bytecode
+ * transformations. These optimizations are the following:
+ *
+ * <ul>
+ * <li>The constant pool and bootstrap methods from the original class are copied as is in the
+ * new class, which saves time. New constant pool entries and new bootstrap methods will be
+ * added at the end if necessary, but unused constant pool entries or bootstrap methods
+ * <i>won't be removed</i>.
+ * <li>Methods that are not transformed are copied as is in the new class, directly from the
+ * original class bytecode (i.e. without emitting visit events for all the method
+ * instructions), which saves a <i>lot</i> of time. Untransformed methods are detected by
+ * the fact that the {@link ClassReader} receives {@link MethodVisitor} objects that come
+ * from a {@link ClassWriter} (and not from any other {@link ClassVisitor} instance).
+ * </ul>
+ *
+ * @param classReader the {@link ClassReader} used to read the original class. It will be used to
+ * copy the entire constant pool and bootstrap methods from the original class and also to
+ * copy other fragments of original bytecode where applicable.
+ * @param flags option flags that can be used to modify the default behavior of this class. Must
+ * be zero or more of {@link #COMPUTE_MAXS} and {@link #COMPUTE_FRAMES}. <i>These option flags
+ * do not affect methods that are copied as is in the new class. This means that neither the
+ * maximum stack size nor the stack frames will be computed for these methods</i>.
+ */
+ public ClassWriter(final ClassReader classReader, final int flags) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.flags = flags;
+ symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader);
+ if ((flags & COMPUTE_FRAMES) != 0) {
+ compute = MethodWriter.COMPUTE_ALL_FRAMES;
+ } else if ((flags & COMPUTE_MAXS) != 0) {
+ compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL;
+ } else {
+ compute = MethodWriter.COMPUTE_NOTHING;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Accessors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns true if all the given flags were passed to the constructor.
+ *
+ * @param flags some option flags. Must be zero or more of {@link #COMPUTE_MAXS} and {@link
+ * #COMPUTE_FRAMES}.
+ * @return true if all the given flags, or more, were passed to the constructor.
+ */
+ public boolean hasFlags(final int flags) {
+ return (this.flags & flags) == flags;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the ClassVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public final void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ this.version = version;
+ this.accessFlags = access;
+ this.thisClass = symbolTable.setMajorVersionAndClassName(version & 0xFFFF, name);
+ if (signature != null) {
+ this.signatureIndex = symbolTable.addConstantUtf8(signature);
+ }
+ this.superClass = superName == null ? 0 : symbolTable.addConstantClass(superName).index;
+ if (interfaces != null && interfaces.length > 0) {
+ interfaceCount = interfaces.length;
+ this.interfaces = new int[interfaceCount];
+ for (int i = 0; i < interfaceCount; ++i) {
+ this.interfaces[i] = symbolTable.addConstantClass(interfaces[i]).index;
+ }
+ }
+ if (compute == MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL && (version & 0xFFFF) >= Opcodes.V1_7) {
+ compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES;
+ }
+ }
+
+ @Override
+ public final void visitSource(final String file, final String debug) {
+ if (file != null) {
+ sourceFileIndex = symbolTable.addConstantUtf8(file);
+ }
+ if (debug != null) {
+ debugExtension = new ByteVector().encodeUtf8(debug, 0, Integer.MAX_VALUE);
+ }
+ }
+
+ @Override
+ public final ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ return moduleWriter =
+ new ModuleWriter(
+ symbolTable,
+ symbolTable.addConstantModule(name).index,
+ access,
+ version == null ? 0 : symbolTable.addConstantUtf8(version));
+ }
+
+ @Override
+ public final void visitNestHost(final String nestHost) {
+ nestHostClassIndex = symbolTable.addConstantClass(nestHost).index;
+ }
+
+ @Override
+ public final void visitOuterClass(
+ final String owner, final String name, final String descriptor) {
+ enclosingClassIndex = symbolTable.addConstantClass(owner).index;
+ if (name != null && descriptor != null) {
+ enclosingMethodIndex = symbolTable.addConstantNameAndType(name, descriptor);
+ }
+ }
+
+ @Override
+ public final AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeVisibleAnnotation);
+ } else {
+ return lastRuntimeInvisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeInvisibleAnnotation);
+ }
+ }
+
+ @Override
+ public final AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public final void visitAttribute(final Attribute attribute) {
+ // Store the attributes in the <i>reverse</i> order of their visit by this method.
+ attribute.nextAttribute = firstAttribute;
+ firstAttribute = attribute;
+ }
+
+ @Override
+ public final void visitNestMember(final String nestMember) {
+ if (nestMemberClasses == null) {
+ nestMemberClasses = new ByteVector();
+ }
+ ++numberOfNestMemberClasses;
+ nestMemberClasses.putShort(symbolTable.addConstantClass(nestMember).index);
+ }
+
+ @Override
+ public final void visitPermittedSubclass(final String permittedSubclass) {
+ if (permittedSubclasses == null) {
+ permittedSubclasses = new ByteVector();
+ }
+ ++numberOfPermittedSubclasses;
+ permittedSubclasses.putShort(symbolTable.addConstantClass(permittedSubclass).index);
+ }
+
+ @Override
+ public final void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ if (innerClasses == null) {
+ innerClasses = new ByteVector();
+ }
+ // Section 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the constant_pool table
+ // which represents a class or interface C that is not a package member must have exactly one
+ // corresponding entry in the classes array". To avoid duplicates we keep track in the info
+ // field of the Symbol of each CONSTANT_Class_info entry C whether an inner class entry has
+ // already been added for C. If so, we store the index of this inner class entry (plus one) in
+ // the info field. This trick allows duplicate detection in O(1) time.
+ Symbol nameSymbol = symbolTable.addConstantClass(name);
+ if (nameSymbol.info == 0) {
+ ++numberOfInnerClasses;
+ innerClasses.putShort(nameSymbol.index);
+ innerClasses.putShort(outerName == null ? 0 : symbolTable.addConstantClass(outerName).index);
+ innerClasses.putShort(innerName == null ? 0 : symbolTable.addConstantUtf8(innerName));
+ innerClasses.putShort(access);
+ nameSymbol.info = numberOfInnerClasses;
+ }
+ // Else, compare the inner classes entry nameSymbol.info - 1 with the arguments of this method
+ // and throw an exception if there is a difference?
+ }
+
+ @Override
+ public final RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ RecordComponentWriter recordComponentWriter =
+ new RecordComponentWriter(symbolTable, name, descriptor, signature);
+ if (firstRecordComponent == null) {
+ firstRecordComponent = recordComponentWriter;
+ } else {
+ lastRecordComponent.delegate = recordComponentWriter;
+ }
+ return lastRecordComponent = recordComponentWriter;
+ }
+
+ @Override
+ public final FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ FieldWriter fieldWriter =
+ new FieldWriter(symbolTable, access, name, descriptor, signature, value);
+ if (firstField == null) {
+ firstField = fieldWriter;
+ } else {
+ lastField.fv = fieldWriter;
+ }
+ return lastField = fieldWriter;
+ }
+
+ @Override
+ public final MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ MethodWriter methodWriter =
+ new MethodWriter(symbolTable, access, name, descriptor, signature, exceptions, compute);
+ if (firstMethod == null) {
+ firstMethod = methodWriter;
+ } else {
+ lastMethod.mv = methodWriter;
+ }
+ return lastMethod = methodWriter;
+ }
+
+ @Override
+ public final void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Other public methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the content of the class file that was built by this ClassWriter.
+ *
+ * @return the binary content of the JVMS ClassFile structure that was built by this ClassWriter.
+ * @throws ClassTooLargeException if the constant pool of the class is too large.
+ * @throws MethodTooLargeException if the Code attribute of a method is too large.
+ */
+ public byte[] toByteArray() {
+ // First step: compute the size in bytes of the ClassFile structure.
+ // The magic field uses 4 bytes, 10 mandatory fields (minor_version, major_version,
+ // constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count,
+ // methods_count and attributes_count) use 2 bytes each, and each interface uses 2 bytes too.
+ int size = 24 + 2 * interfaceCount;
+ int fieldsCount = 0;
+ FieldWriter fieldWriter = firstField;
+ while (fieldWriter != null) {
+ ++fieldsCount;
+ size += fieldWriter.computeFieldInfoSize();
+ fieldWriter = (FieldWriter) fieldWriter.fv;
+ }
+ int methodsCount = 0;
+ MethodWriter methodWriter = firstMethod;
+ while (methodWriter != null) {
+ ++methodsCount;
+ size += methodWriter.computeMethodInfoSize();
+ methodWriter = (MethodWriter) methodWriter.mv;
+ }
+
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ int attributesCount = 0;
+ if (innerClasses != null) {
+ ++attributesCount;
+ size += 8 + innerClasses.length;
+ symbolTable.addConstantUtf8(Constants.INNER_CLASSES);
+ }
+ if (enclosingClassIndex != 0) {
+ ++attributesCount;
+ size += 10;
+ symbolTable.addConstantUtf8(Constants.ENCLOSING_METHOD);
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && (version & 0xFFFF) < Opcodes.V1_5) {
+ ++attributesCount;
+ size += 6;
+ symbolTable.addConstantUtf8(Constants.SYNTHETIC);
+ }
+ if (signatureIndex != 0) {
+ ++attributesCount;
+ size += 8;
+ symbolTable.addConstantUtf8(Constants.SIGNATURE);
+ }
+ if (sourceFileIndex != 0) {
+ ++attributesCount;
+ size += 8;
+ symbolTable.addConstantUtf8(Constants.SOURCE_FILE);
+ }
+ if (debugExtension != null) {
+ ++attributesCount;
+ size += 6 + debugExtension.length;
+ symbolTable.addConstantUtf8(Constants.SOURCE_DEBUG_EXTENSION);
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ ++attributesCount;
+ size += 6;
+ symbolTable.addConstantUtf8(Constants.DEPRECATED);
+ }
+ if (lastRuntimeVisibleAnnotation != null) {
+ ++attributesCount;
+ size +=
+ lastRuntimeVisibleAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_ANNOTATIONS);
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ ++attributesCount;
+ size +=
+ lastRuntimeInvisibleAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_ANNOTATIONS);
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ ++attributesCount;
+ size +=
+ lastRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ ++attributesCount;
+ size +=
+ lastRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (symbolTable.computeBootstrapMethodsSize() > 0) {
+ ++attributesCount;
+ size += symbolTable.computeBootstrapMethodsSize();
+ }
+ if (moduleWriter != null) {
+ attributesCount += moduleWriter.getAttributeCount();
+ size += moduleWriter.computeAttributesSize();
+ }
+ if (nestHostClassIndex != 0) {
+ ++attributesCount;
+ size += 8;
+ symbolTable.addConstantUtf8(Constants.NEST_HOST);
+ }
+ if (nestMemberClasses != null) {
+ ++attributesCount;
+ size += 8 + nestMemberClasses.length;
+ symbolTable.addConstantUtf8(Constants.NEST_MEMBERS);
+ }
+ if (permittedSubclasses != null) {
+ ++attributesCount;
+ size += 8 + permittedSubclasses.length;
+ symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES);
+ }
+ int recordComponentCount = 0;
+ int recordSize = 0;
+ if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) {
+ RecordComponentWriter recordComponentWriter = firstRecordComponent;
+ while (recordComponentWriter != null) {
+ ++recordComponentCount;
+ recordSize += recordComponentWriter.computeRecordComponentInfoSize();
+ recordComponentWriter = (RecordComponentWriter) recordComponentWriter.delegate;
+ }
+ ++attributesCount;
+ size += 8 + recordSize;
+ symbolTable.addConstantUtf8(Constants.RECORD);
+ }
+ if (firstAttribute != null) {
+ attributesCount += firstAttribute.getAttributeCount();
+ size += firstAttribute.computeAttributesSize(symbolTable);
+ }
+ // IMPORTANT: this must be the last part of the ClassFile size computation, because the previous
+ // statements can add attribute names to the constant pool, thereby changing its size!
+ size += symbolTable.getConstantPoolLength();
+ int constantPoolCount = symbolTable.getConstantPoolCount();
+ if (constantPoolCount > 0xFFFF) {
+ throw new ClassTooLargeException(symbolTable.getClassName(), constantPoolCount);
+ }
+
+ // Second step: allocate a ByteVector of the correct size (in order to avoid any array copy in
+ // dynamic resizes) and fill it with the ClassFile content.
+ ByteVector result = new ByteVector(size);
+ result.putInt(0xCAFEBABE).putInt(version);
+ symbolTable.putConstantPool(result);
+ int mask = (version & 0xFFFF) < Opcodes.V1_5 ? Opcodes.ACC_SYNTHETIC : 0;
+ result.putShort(accessFlags & ~mask).putShort(thisClass).putShort(superClass);
+ result.putShort(interfaceCount);
+ for (int i = 0; i < interfaceCount; ++i) {
+ result.putShort(interfaces[i]);
+ }
+ result.putShort(fieldsCount);
+ fieldWriter = firstField;
+ while (fieldWriter != null) {
+ fieldWriter.putFieldInfo(result);
+ fieldWriter = (FieldWriter) fieldWriter.fv;
+ }
+ result.putShort(methodsCount);
+ boolean hasFrames = false;
+ boolean hasAsmInstructions = false;
+ methodWriter = firstMethod;
+ while (methodWriter != null) {
+ hasFrames |= methodWriter.hasFrames();
+ hasAsmInstructions |= methodWriter.hasAsmInstructions();
+ methodWriter.putMethodInfo(result);
+ methodWriter = (MethodWriter) methodWriter.mv;
+ }
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ result.putShort(attributesCount);
+ if (innerClasses != null) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.INNER_CLASSES))
+ .putInt(innerClasses.length + 2)
+ .putShort(numberOfInnerClasses)
+ .putByteArray(innerClasses.data, 0, innerClasses.length);
+ }
+ if (enclosingClassIndex != 0) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.ENCLOSING_METHOD))
+ .putInt(4)
+ .putShort(enclosingClassIndex)
+ .putShort(enclosingMethodIndex);
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && (version & 0xFFFF) < Opcodes.V1_5) {
+ result.putShort(symbolTable.addConstantUtf8(Constants.SYNTHETIC)).putInt(0);
+ }
+ if (signatureIndex != 0) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.SIGNATURE))
+ .putInt(2)
+ .putShort(signatureIndex);
+ }
+ if (sourceFileIndex != 0) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.SOURCE_FILE))
+ .putInt(2)
+ .putShort(sourceFileIndex);
+ }
+ if (debugExtension != null) {
+ int length = debugExtension.length;
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.SOURCE_DEBUG_EXTENSION))
+ .putInt(length)
+ .putByteArray(debugExtension.data, 0, length);
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ result.putShort(symbolTable.addConstantUtf8(Constants.DEPRECATED)).putInt(0);
+ }
+ AnnotationWriter.putAnnotations(
+ symbolTable,
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation,
+ result);
+ symbolTable.putBootstrapMethods(result);
+ if (moduleWriter != null) {
+ moduleWriter.putAttributes(result);
+ }
+ if (nestHostClassIndex != 0) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.NEST_HOST))
+ .putInt(2)
+ .putShort(nestHostClassIndex);
+ }
+ if (nestMemberClasses != null) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.NEST_MEMBERS))
+ .putInt(nestMemberClasses.length + 2)
+ .putShort(numberOfNestMemberClasses)
+ .putByteArray(nestMemberClasses.data, 0, nestMemberClasses.length);
+ }
+ if (permittedSubclasses != null) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBCLASSES))
+ .putInt(permittedSubclasses.length + 2)
+ .putShort(numberOfPermittedSubclasses)
+ .putByteArray(permittedSubclasses.data, 0, permittedSubclasses.length);
+ }
+ if ((accessFlags & Opcodes.ACC_RECORD) != 0 || firstRecordComponent != null) {
+ result
+ .putShort(symbolTable.addConstantUtf8(Constants.RECORD))
+ .putInt(recordSize + 2)
+ .putShort(recordComponentCount);
+ RecordComponentWriter recordComponentWriter = firstRecordComponent;
+ while (recordComponentWriter != null) {
+ recordComponentWriter.putRecordComponentInfo(result);
+ recordComponentWriter = (RecordComponentWriter) recordComponentWriter.delegate;
+ }
+ }
+ if (firstAttribute != null) {
+ firstAttribute.putAttributes(symbolTable, result);
+ }
+
+ // Third step: replace the ASM specific instructions, if any.
+ if (hasAsmInstructions) {
+ return replaceAsmInstructions(result.data, hasFrames);
+ } else {
+ return result.data;
+ }
+ }
+
+ /**
+ * Returns the equivalent of the given class file, with the ASM specific instructions replaced
+ * with standard ones. This is done with a ClassReader -&gt; ClassWriter round trip.
+ *
+ * @param classFile a class file containing ASM specific instructions, generated by this
+ * ClassWriter.
+ * @param hasFrames whether there is at least one stack map frames in 'classFile'.
+ * @return an equivalent of 'classFile', with the ASM specific instructions replaced with standard
+ * ones.
+ */
+ private byte[] replaceAsmInstructions(final byte[] classFile, final boolean hasFrames) {
+ final Attribute[] attributes = getAttributePrototypes();
+ firstField = null;
+ lastField = null;
+ firstMethod = null;
+ lastMethod = null;
+ lastRuntimeVisibleAnnotation = null;
+ lastRuntimeInvisibleAnnotation = null;
+ lastRuntimeVisibleTypeAnnotation = null;
+ lastRuntimeInvisibleTypeAnnotation = null;
+ moduleWriter = null;
+ nestHostClassIndex = 0;
+ numberOfNestMemberClasses = 0;
+ nestMemberClasses = null;
+ numberOfPermittedSubclasses = 0;
+ permittedSubclasses = null;
+ firstRecordComponent = null;
+ lastRecordComponent = null;
+ firstAttribute = null;
+ compute = hasFrames ? MethodWriter.COMPUTE_INSERTED_FRAMES : MethodWriter.COMPUTE_NOTHING;
+ new ClassReader(classFile, 0, /* checkClassVersion = */ false)
+ .accept(
+ this,
+ attributes,
+ (hasFrames ? ClassReader.EXPAND_FRAMES : 0) | ClassReader.EXPAND_ASM_INSNS);
+ return toByteArray();
+ }
+
+ /**
+ * Returns the prototypes of the attributes used by this class, its fields and its methods.
+ *
+ * @return the prototypes of the attributes used by this class, its fields and its methods.
+ */
+ private Attribute[] getAttributePrototypes() {
+ Attribute.Set attributePrototypes = new Attribute.Set();
+ attributePrototypes.addAttributes(firstAttribute);
+ FieldWriter fieldWriter = firstField;
+ while (fieldWriter != null) {
+ fieldWriter.collectAttributePrototypes(attributePrototypes);
+ fieldWriter = (FieldWriter) fieldWriter.fv;
+ }
+ MethodWriter methodWriter = firstMethod;
+ while (methodWriter != null) {
+ methodWriter.collectAttributePrototypes(attributePrototypes);
+ methodWriter = (MethodWriter) methodWriter.mv;
+ }
+ RecordComponentWriter recordComponentWriter = firstRecordComponent;
+ while (recordComponentWriter != null) {
+ recordComponentWriter.collectAttributePrototypes(attributePrototypes);
+ recordComponentWriter = (RecordComponentWriter) recordComponentWriter.delegate;
+ }
+ return attributePrototypes.toArray();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods: constant pool management for Attribute sub classes
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds a number or string constant to the constant pool of the class being build. Does nothing if
+ * the constant pool already contains a similar item. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param value the value of the constant to be added to the constant pool. This parameter must be
+ * an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
+ * @return the index of a new or already existing constant item with the given value.
+ */
+ public int newConst(final Object value) {
+ return symbolTable.addConstant(value).index;
+ }
+
+ /**
+ * Adds an UTF8 string to the constant pool of the class being build. Does nothing if the constant
+ * pool already contains a similar item. <i>This method is intended for {@link Attribute} sub
+ * classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param value the String value.
+ * @return the index of a new or already existing UTF8 item.
+ */
+ // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility).
+ public int newUTF8(final String value) {
+ return symbolTable.addConstantUtf8(value);
+ }
+
+ /**
+ * Adds a class reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param value the internal name of the class (see {@link Type#getInternalName()}).
+ * @return the index of a new or already existing class reference item.
+ */
+ public int newClass(final String value) {
+ return symbolTable.addConstantClass(value).index;
+ }
+
+ /**
+ * Adds a method type reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param methodDescriptor method descriptor of the method type.
+ * @return the index of a new or already existing method type reference item.
+ */
+ public int newMethodType(final String methodDescriptor) {
+ return symbolTable.addConstantMethodType(methodDescriptor).index;
+ }
+
+ /**
+ * Adds a module reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param moduleName name of the module.
+ * @return the index of a new or already existing module reference item.
+ */
+ public int newModule(final String moduleName) {
+ return symbolTable.addConstantModule(moduleName).index;
+ }
+
+ /**
+ * Adds a package reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param packageName name of the package in its internal form.
+ * @return the index of a new or already existing module reference item.
+ */
+ public int newPackage(final String packageName) {
+ return symbolTable.addConstantPackage(packageName).index;
+ }
+
+ /**
+ * Adds a handle to the constant pool of the class being build. Does nothing if the constant pool
+ * already contains a similar item. <i>This method is intended for {@link Attribute} sub classes,
+ * and is normally not needed by class generators or adapters.</i>
+ *
+ * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, {@link
+ * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link
+ * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of the field or method owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the field or method.
+ * @param descriptor the descriptor of the field or method.
+ * @return the index of a new or already existing method type reference item.
+ * @deprecated this method is superseded by {@link #newHandle(int, String, String, String,
+ * boolean)}.
+ */
+ @Deprecated
+ public int newHandle(
+ final int tag, final String owner, final String name, final String descriptor) {
+ return newHandle(tag, owner, name, descriptor, tag == Opcodes.H_INVOKEINTERFACE);
+ }
+
+ /**
+ * Adds a handle to the constant pool of the class being build. Does nothing if the constant pool
+ * already contains a similar item. <i>This method is intended for {@link Attribute} sub classes,
+ * and is normally not needed by class generators or adapters.</i>
+ *
+ * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, {@link
+ * Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link
+ * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of the field or method owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the name of the field or method.
+ * @param descriptor the descriptor of the field or method.
+ * @param isInterface true if the owner is an interface.
+ * @return the index of a new or already existing method type reference item.
+ */
+ public int newHandle(
+ final int tag,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ return symbolTable.addConstantMethodHandle(tag, owner, name, descriptor, isInterface).index;
+ }
+
+ /**
+ * Adds a dynamic constant reference to the constant pool of the class being build. Does nothing
+ * if the constant pool already contains a similar item. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param name name of the invoked method.
+ * @param descriptor field descriptor of the constant type.
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments.
+ * @return the index of a new or already existing dynamic constant reference item.
+ */
+ public int newConstantDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ return symbolTable.addConstantDynamic(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
+ .index;
+ }
+
+ /**
+ * Adds an invokedynamic reference to the constant pool of the class being build. Does nothing if
+ * the constant pool already contains a similar item. <i>This method is intended for {@link
+ * Attribute} sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param name name of the invoked method.
+ * @param descriptor descriptor of the invoke method.
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments.
+ * @return the index of a new or already existing invokedynamic reference item.
+ */
+ public int newInvokeDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ return symbolTable.addConstantInvokeDynamic(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
+ .index;
+ }
+
+ /**
+ * Adds a field reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}).
+ * @param name the field's name.
+ * @param descriptor the field's descriptor.
+ * @return the index of a new or already existing field reference item.
+ */
+ public int newField(final String owner, final String name, final String descriptor) {
+ return symbolTable.addConstantFieldref(owner, name, descriptor).index;
+ }
+
+ /**
+ * Adds a method reference to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor.
+ * @param isInterface {@literal true} if {@code owner} is an interface.
+ * @return the index of a new or already existing method reference item.
+ */
+ public int newMethod(
+ final String owner, final String name, final String descriptor, final boolean isInterface) {
+ return symbolTable.addConstantMethodref(owner, name, descriptor, isInterface).index;
+ }
+
+ /**
+ * Adds a name and type to the constant pool of the class being build. Does nothing if the
+ * constant pool already contains a similar item. <i>This method is intended for {@link Attribute}
+ * sub classes, and is normally not needed by class generators or adapters.</i>
+ *
+ * @param name a name.
+ * @param descriptor a type descriptor.
+ * @return the index of a new or already existing name and type item.
+ */
+ public int newNameType(final String name, final String descriptor) {
+ return symbolTable.addConstantNameAndType(name, descriptor);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Default method to compute common super classes when computing stack map frames
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the common super type of the two given types. The default implementation of this method
+ * <i>loads</i> the two given classes and uses the java.lang.Class methods to find the common
+ * super class. It can be overridden to compute this common super type in other ways, in
+ * particular without actually loading any class, or to take into account the class that is
+ * currently being generated by this ClassWriter, which can of course not be loaded since it is
+ * under construction.
+ *
+ * @param type1 the internal name of a class (see {@link Type#getInternalName()}).
+ * @param type2 the internal name of another class (see {@link Type#getInternalName()}).
+ * @return the internal name of the common super class of the two given classes (see {@link
+ * Type#getInternalName()}).
+ */
+ protected String getCommonSuperClass(final String type1, final String type2) {
+ ClassLoader classLoader = getClassLoader();
+ Class<?> class1;
+ try {
+ class1 = Class.forName(type1.replace('/', '.'), false, classLoader);
+ } catch (ClassNotFoundException e) {
+ throw new TypeNotPresentException(type1, e);
+ }
+ Class<?> class2;
+ try {
+ class2 = Class.forName(type2.replace('/', '.'), false, classLoader);
+ } catch (ClassNotFoundException e) {
+ throw new TypeNotPresentException(type2, e);
+ }
+ if (class1.isAssignableFrom(class2)) {
+ return type1;
+ }
+ if (class2.isAssignableFrom(class1)) {
+ return type2;
+ }
+ if (class1.isInterface() || class2.isInterface()) {
+ return "java/lang/Object";
+ } else {
+ do {
+ class1 = class1.getSuperclass();
+ } while (!class1.isAssignableFrom(class2));
+ return class1.getName().replace('.', '/');
+ }
+ }
+
+ /**
+ * Returns the {@link ClassLoader} to be used by the default implementation of {@link
+ * #getCommonSuperClass(String, String)}, that of this {@link ClassWriter}'s runtime type by
+ * default.
+ *
+ * @return ClassLoader
+ */
+ protected ClassLoader getClassLoader() {
+ return getClass().getClassLoader();
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ConstantDynamic.java b/asm/src/main/java/org/objectweb/asm/ConstantDynamic.java
new file mode 100644
index 00000000..f3d21277
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ConstantDynamic.java
@@ -0,0 +1,178 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import java.util.Arrays;
+
+/**
+ * A constant whose value is computed at runtime, with a bootstrap method.
+ *
+ * @author Remi Forax
+ */
+public final class ConstantDynamic {
+
+ /** The constant name (can be arbitrary). */
+ private final String name;
+
+ /** The constant type (must be a field descriptor). */
+ private final String descriptor;
+
+ /** The bootstrap method to use to compute the constant value at runtime. */
+ private final Handle bootstrapMethod;
+
+ /**
+ * The arguments to pass to the bootstrap method, in order to compute the constant value at
+ * runtime.
+ */
+ private final Object[] bootstrapMethodArguments;
+
+ /**
+ * Constructs a new {@link ConstantDynamic}.
+ *
+ * @param name the constant name (can be arbitrary).
+ * @param descriptor the constant type (must be a field descriptor).
+ * @param bootstrapMethod the bootstrap method to use to compute the constant value at runtime.
+ * @param bootstrapMethodArguments the arguments to pass to the bootstrap method, in order to
+ * compute the constant value at runtime.
+ */
+ public ConstantDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethod,
+ final Object... bootstrapMethodArguments) {
+ this.name = name;
+ this.descriptor = descriptor;
+ this.bootstrapMethod = bootstrapMethod;
+ this.bootstrapMethodArguments = bootstrapMethodArguments;
+ }
+
+ /**
+ * Returns the name of this constant.
+ *
+ * @return the name of this constant.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the type of this constant.
+ *
+ * @return the type of this constant, as a field descriptor.
+ */
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the bootstrap method used to compute the value of this constant.
+ *
+ * @return the bootstrap method used to compute the value of this constant.
+ */
+ public Handle getBootstrapMethod() {
+ return bootstrapMethod;
+ }
+
+ /**
+ * Returns the number of arguments passed to the bootstrap method, in order to compute the value
+ * of this constant.
+ *
+ * @return the number of arguments passed to the bootstrap method, in order to compute the value
+ * of this constant.
+ */
+ public int getBootstrapMethodArgumentCount() {
+ return bootstrapMethodArguments.length;
+ }
+
+ /**
+ * Returns an argument passed to the bootstrap method, in order to compute the value of this
+ * constant.
+ *
+ * @param index an argument index, between 0 and {@link #getBootstrapMethodArgumentCount()}
+ * (exclusive).
+ * @return the argument passed to the bootstrap method, with the given index.
+ */
+ public Object getBootstrapMethodArgument(final int index) {
+ return bootstrapMethodArguments[index];
+ }
+
+ /**
+ * Returns the arguments to pass to the bootstrap method, in order to compute the value of this
+ * constant. WARNING: this array must not be modified, and must not be returned to the user.
+ *
+ * @return the arguments to pass to the bootstrap method, in order to compute the value of this
+ * constant.
+ */
+ Object[] getBootstrapMethodArgumentsUnsafe() {
+ return bootstrapMethodArguments;
+ }
+
+ /**
+ * Returns the size of this constant.
+ *
+ * @return the size of this constant, i.e., 2 for {@code long} and {@code double}, 1 otherwise.
+ */
+ public int getSize() {
+ char firstCharOfDescriptor = descriptor.charAt(0);
+ return (firstCharOfDescriptor == 'J' || firstCharOfDescriptor == 'D') ? 2 : 1;
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof ConstantDynamic)) {
+ return false;
+ }
+ ConstantDynamic constantDynamic = (ConstantDynamic) object;
+ return name.equals(constantDynamic.name)
+ && descriptor.equals(constantDynamic.descriptor)
+ && bootstrapMethod.equals(constantDynamic.bootstrapMethod)
+ && Arrays.equals(bootstrapMethodArguments, constantDynamic.bootstrapMethodArguments);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode()
+ ^ Integer.rotateLeft(descriptor.hashCode(), 8)
+ ^ Integer.rotateLeft(bootstrapMethod.hashCode(), 16)
+ ^ Integer.rotateLeft(Arrays.hashCode(bootstrapMethodArguments), 24);
+ }
+
+ @Override
+ public String toString() {
+ return name
+ + " : "
+ + descriptor
+ + ' '
+ + bootstrapMethod
+ + ' '
+ + Arrays.toString(bootstrapMethodArguments);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Constants.java b/asm/src/main/java/org/objectweb/asm/Constants.java
new file mode 100644
index 00000000..ff32798d
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Constants.java
@@ -0,0 +1,221 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+/**
+ * Defines additional JVM opcodes, access flags and constants which are not part of the ASM public
+ * API.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html">JVMS 6</a>
+ * @author Eric Bruneton
+ */
+final class Constants {
+
+ // The ClassFile attribute names, in the order they are defined in
+ // https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7-300.
+
+ static final String CONSTANT_VALUE = "ConstantValue";
+ static final String CODE = "Code";
+ static final String STACK_MAP_TABLE = "StackMapTable";
+ static final String EXCEPTIONS = "Exceptions";
+ static final String INNER_CLASSES = "InnerClasses";
+ static final String ENCLOSING_METHOD = "EnclosingMethod";
+ static final String SYNTHETIC = "Synthetic";
+ static final String SIGNATURE = "Signature";
+ static final String SOURCE_FILE = "SourceFile";
+ static final String SOURCE_DEBUG_EXTENSION = "SourceDebugExtension";
+ static final String LINE_NUMBER_TABLE = "LineNumberTable";
+ static final String LOCAL_VARIABLE_TABLE = "LocalVariableTable";
+ static final String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
+ static final String DEPRECATED = "Deprecated";
+ static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
+ static final String RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
+ static final String RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
+ static final String RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS =
+ "RuntimeInvisibleParameterAnnotations";
+ static final String RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
+ static final String RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations";
+ static final String ANNOTATION_DEFAULT = "AnnotationDefault";
+ static final String BOOTSTRAP_METHODS = "BootstrapMethods";
+ static final String METHOD_PARAMETERS = "MethodParameters";
+ static final String MODULE = "Module";
+ static final String MODULE_PACKAGES = "ModulePackages";
+ static final String MODULE_MAIN_CLASS = "ModuleMainClass";
+ static final String NEST_HOST = "NestHost";
+ static final String NEST_MEMBERS = "NestMembers";
+ static final String PERMITTED_SUBCLASSES = "PermittedSubclasses";
+ static final String RECORD = "Record";
+
+ // ASM specific access flags.
+ // WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard
+ // access flags, and also to make sure that these flags are automatically filtered out when
+ // written in class files (because access flags are stored using 16 bits only).
+
+ static final int ACC_CONSTRUCTOR = 0x40000; // method access flag.
+
+ // ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}.
+
+ /**
+ * A frame inserted between already existing frames. This internal stack map frame type (in
+ * addition to the ones declared in {@link Opcodes}) can only be used if the frame content can be
+ * computed from the previous existing frame and from the instructions between this existing frame
+ * and the inserted one, without any knowledge of the type hierarchy. This kind of frame is only
+ * used when an unconditional jump is inserted in a method while expanding an ASM specific
+ * instruction. Keep in sync with Opcodes.java.
+ */
+ static final int F_INSERT = 256;
+
+ // The JVM opcode values which are not part of the ASM public API.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html.
+
+ static final int LDC_W = 19;
+ static final int LDC2_W = 20;
+ static final int ILOAD_0 = 26;
+ static final int ILOAD_1 = 27;
+ static final int ILOAD_2 = 28;
+ static final int ILOAD_3 = 29;
+ static final int LLOAD_0 = 30;
+ static final int LLOAD_1 = 31;
+ static final int LLOAD_2 = 32;
+ static final int LLOAD_3 = 33;
+ static final int FLOAD_0 = 34;
+ static final int FLOAD_1 = 35;
+ static final int FLOAD_2 = 36;
+ static final int FLOAD_3 = 37;
+ static final int DLOAD_0 = 38;
+ static final int DLOAD_1 = 39;
+ static final int DLOAD_2 = 40;
+ static final int DLOAD_3 = 41;
+ static final int ALOAD_0 = 42;
+ static final int ALOAD_1 = 43;
+ static final int ALOAD_2 = 44;
+ static final int ALOAD_3 = 45;
+ static final int ISTORE_0 = 59;
+ static final int ISTORE_1 = 60;
+ static final int ISTORE_2 = 61;
+ static final int ISTORE_3 = 62;
+ static final int LSTORE_0 = 63;
+ static final int LSTORE_1 = 64;
+ static final int LSTORE_2 = 65;
+ static final int LSTORE_3 = 66;
+ static final int FSTORE_0 = 67;
+ static final int FSTORE_1 = 68;
+ static final int FSTORE_2 = 69;
+ static final int FSTORE_3 = 70;
+ static final int DSTORE_0 = 71;
+ static final int DSTORE_1 = 72;
+ static final int DSTORE_2 = 73;
+ static final int DSTORE_3 = 74;
+ static final int ASTORE_0 = 75;
+ static final int ASTORE_1 = 76;
+ static final int ASTORE_2 = 77;
+ static final int ASTORE_3 = 78;
+ static final int WIDE = 196;
+ static final int GOTO_W = 200;
+ static final int JSR_W = 201;
+
+ // Constants to convert between normal and wide jump instructions.
+
+ // The delta between the GOTO_W and JSR_W opcodes and GOTO and JUMP.
+ static final int WIDE_JUMP_OPCODE_DELTA = GOTO_W - Opcodes.GOTO;
+
+ // Constants to convert JVM opcodes to the equivalent ASM specific opcodes, and vice versa.
+
+ // The delta between the ASM_IFEQ, ..., ASM_IF_ACMPNE, ASM_GOTO and ASM_JSR opcodes
+ // and IFEQ, ..., IF_ACMPNE, GOTO and JSR.
+ static final int ASM_OPCODE_DELTA = 49;
+
+ // The delta between the ASM_IFNULL and ASM_IFNONNULL opcodes and IFNULL and IFNONNULL.
+ static final int ASM_IFNULL_OPCODE_DELTA = 20;
+
+ // ASM specific opcodes, used for long forward jump instructions.
+
+ static final int ASM_IFEQ = Opcodes.IFEQ + ASM_OPCODE_DELTA;
+ static final int ASM_IFNE = Opcodes.IFNE + ASM_OPCODE_DELTA;
+ static final int ASM_IFLT = Opcodes.IFLT + ASM_OPCODE_DELTA;
+ static final int ASM_IFGE = Opcodes.IFGE + ASM_OPCODE_DELTA;
+ static final int ASM_IFGT = Opcodes.IFGT + ASM_OPCODE_DELTA;
+ static final int ASM_IFLE = Opcodes.IFLE + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPEQ = Opcodes.IF_ICMPEQ + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPNE = Opcodes.IF_ICMPNE + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPLT = Opcodes.IF_ICMPLT + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPGE = Opcodes.IF_ICMPGE + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPGT = Opcodes.IF_ICMPGT + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ICMPLE = Opcodes.IF_ICMPLE + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ACMPEQ = Opcodes.IF_ACMPEQ + ASM_OPCODE_DELTA;
+ static final int ASM_IF_ACMPNE = Opcodes.IF_ACMPNE + ASM_OPCODE_DELTA;
+ static final int ASM_GOTO = Opcodes.GOTO + ASM_OPCODE_DELTA;
+ static final int ASM_JSR = Opcodes.JSR + ASM_OPCODE_DELTA;
+ static final int ASM_IFNULL = Opcodes.IFNULL + ASM_IFNULL_OPCODE_DELTA;
+ static final int ASM_IFNONNULL = Opcodes.IFNONNULL + ASM_IFNULL_OPCODE_DELTA;
+ static final int ASM_GOTO_W = 220;
+
+ private Constants() {}
+
+ static void checkAsmExperimental(final Object caller) {
+ Class<?> callerClass = caller.getClass();
+ String internalName = callerClass.getName().replace('.', '/');
+ if (!isWhitelisted(internalName)) {
+ checkIsPreview(callerClass.getClassLoader().getResourceAsStream(internalName + ".class"));
+ }
+ }
+
+ static boolean isWhitelisted(final String internalName) {
+ if (!internalName.startsWith("org/objectweb/asm/")) {
+ return false;
+ }
+ String member = "(Annotation|Class|Field|Method|Module|RecordComponent|Signature)";
+ return internalName.contains("Test$")
+ || Pattern.matches(
+ "org/objectweb/asm/util/Trace" + member + "Visitor(\\$.*)?", internalName)
+ || Pattern.matches(
+ "org/objectweb/asm/util/Check" + member + "Adapter(\\$.*)?", internalName);
+ }
+
+ static void checkIsPreview(final InputStream classInputStream) {
+ if (classInputStream == null) {
+ throw new IllegalStateException("Bytecode not available, can't check class version");
+ }
+ int minorVersion;
+ try (DataInputStream callerClassStream = new DataInputStream(classInputStream); ) {
+ callerClassStream.readInt();
+ minorVersion = callerClassStream.readUnsignedShort();
+ } catch (IOException ioe) {
+ throw new IllegalStateException("I/O error, can't check class version", ioe);
+ }
+ if (minorVersion != 0xFFFF) {
+ throw new IllegalStateException(
+ "ASM9_EXPERIMENTAL can only be used by classes compiled with --enable-preview");
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Context.java b/asm/src/main/java/org/objectweb/asm/Context.java
new file mode 100644
index 00000000..da7bcc79
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Context.java
@@ -0,0 +1,137 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm;
+
+/**
+ * Information about a class being parsed in a {@link ClassReader}.
+ *
+ * @author Eric Bruneton
+ */
+final class Context {
+
+ /** The prototypes of the attributes that must be parsed in this class. */
+ Attribute[] attributePrototypes;
+
+ /**
+ * The options used to parse this class. One or more of {@link ClassReader#SKIP_CODE}, {@link
+ * ClassReader#SKIP_DEBUG}, {@link ClassReader#SKIP_FRAMES}, {@link ClassReader#EXPAND_FRAMES} or
+ * {@link ClassReader#EXPAND_ASM_INSNS}.
+ */
+ int parsingOptions;
+
+ /** The buffer used to read strings in the constant pool. */
+ char[] charBuffer;
+
+ // Information about the current method, i.e. the one read in the current (or latest) call
+ // to {@link ClassReader#readMethod()}.
+
+ /** The access flags of the current method. */
+ int currentMethodAccessFlags;
+
+ /** The name of the current method. */
+ String currentMethodName;
+
+ /** The descriptor of the current method. */
+ String currentMethodDescriptor;
+
+ /**
+ * The labels of the current method, indexed by bytecode offset (only bytecode offsets for which a
+ * label is needed have a non null associated Label).
+ */
+ Label[] currentMethodLabels;
+
+ // Information about the current type annotation target, i.e. the one read in the current
+ // (or latest) call to {@link ClassReader#readAnnotationTarget()}.
+
+ /**
+ * The target_type and target_info of the current type annotation target, encoded as described in
+ * {@link TypeReference}.
+ */
+ int currentTypeAnnotationTarget;
+
+ /** The target_path of the current type annotation target. */
+ TypePath currentTypeAnnotationTargetPath;
+
+ /** The start of each local variable range in the current local variable annotation. */
+ Label[] currentLocalVariableAnnotationRangeStarts;
+
+ /** The end of each local variable range in the current local variable annotation. */
+ Label[] currentLocalVariableAnnotationRangeEnds;
+
+ /**
+ * The local variable index of each local variable range in the current local variable annotation.
+ */
+ int[] currentLocalVariableAnnotationRangeIndices;
+
+ // Information about the current stack map frame, i.e. the one read in the current (or latest)
+ // call to {@link ClassReader#readFrame()}.
+
+ /** The bytecode offset of the current stack map frame. */
+ int currentFrameOffset;
+
+ /**
+ * The type of the current stack map frame. One of {@link Opcodes#F_FULL}, {@link
+ * Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or {@link Opcodes#F_SAME1}.
+ */
+ int currentFrameType;
+
+ /**
+ * The number of local variable types in the current stack map frame. Each type is represented
+ * with a single array element (even long and double).
+ */
+ int currentFrameLocalCount;
+
+ /**
+ * The delta number of local variable types in the current stack map frame (each type is
+ * represented with a single array element - even long and double). This is the number of local
+ * variable types in this frame, minus the number of local variable types in the previous frame.
+ */
+ int currentFrameLocalCountDelta;
+
+ /**
+ * The types of the local variables in the current stack map frame. Each type is represented with
+ * a single array element (even long and double), using the format described in {@link
+ * MethodVisitor#visitFrame}. Depending on {@link #currentFrameType}, this contains the types of
+ * all the local variables, or only those of the additional ones (compared to the previous frame).
+ */
+ Object[] currentFrameLocalTypes;
+
+ /**
+ * The number stack element types in the current stack map frame. Each type is represented with a
+ * single array element (even long and double).
+ */
+ int currentFrameStackCount;
+
+ /**
+ * The types of the stack elements in the current stack map frame. Each type is represented with a
+ * single array element (even long and double), using the format described in {@link
+ * MethodVisitor#visitFrame}.
+ */
+ Object[] currentFrameStackTypes;
+}
diff --git a/asm/src/main/java/org/objectweb/asm/CurrentFrame.java b/asm/src/main/java/org/objectweb/asm/CurrentFrame.java
new file mode 100644
index 00000000..99212a36
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/CurrentFrame.java
@@ -0,0 +1,56 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a method. This is
+ * implemented as a Frame subclass for a "basic block" containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+final class CurrentFrame extends Frame {
+
+ CurrentFrame(final Label owner) {
+ super(owner);
+ }
+
+ /**
+ * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the
+ * instruction just after the given one. It is assumed that the value of this object when this
+ * method is called is the stack map frame status just before the given instruction is executed.
+ */
+ @Override
+ void execute(
+ final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) {
+ super.execute(opcode, arg, symbolArg, symbolTable);
+ Frame successor = new Frame(null);
+ merge(symbolTable, successor, 0);
+ copyFrom(successor);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Edge.java b/asm/src/main/java/org/objectweb/asm/Edge.java
new file mode 100644
index 00000000..2a9e703e
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Edge.java
@@ -0,0 +1,91 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * An edge in the control flow graph of a method. Each node of this graph is a basic block,
+ * represented with the Label corresponding to its first instruction. Each edge goes from one node
+ * to another, i.e. from one basic block to another (called the predecessor and successor blocks,
+ * respectively). An edge corresponds either to a jump or ret instruction or to an exception
+ * handler.
+ *
+ * @see Label
+ * @author Eric Bruneton
+ */
+final class Edge {
+
+ /**
+ * A control flow graph edge corresponding to a jump or ret instruction. Only used with {@link
+ * ClassWriter#COMPUTE_FRAMES}.
+ */
+ static final int JUMP = 0;
+
+ /**
+ * A control flow graph edge corresponding to an exception handler. Only used with {@link
+ * ClassWriter#COMPUTE_MAXS}.
+ */
+ static final int EXCEPTION = 0x7FFFFFFF;
+
+ /**
+ * Information about this control flow graph edge.
+ *
+ * <ul>
+ * <li>If {@link ClassWriter#COMPUTE_MAXS} is used, this field contains either a stack size
+ * delta (for an edge corresponding to a jump instruction), or the value EXCEPTION (for an
+ * edge corresponding to an exception handler). The stack size delta is the stack size just
+ * after the jump instruction, minus the stack size at the beginning of the predecessor
+ * basic block, i.e. the one containing the jump instruction.
+ * <li>If {@link ClassWriter#COMPUTE_FRAMES} is used, this field contains either the value JUMP
+ * (for an edge corresponding to a jump instruction), or the index, in the {@link
+ * ClassWriter} type table, of the exception type that is handled (for an edge corresponding
+ * to an exception handler).
+ * </ul>
+ */
+ final int info;
+
+ /** The successor block of this control flow graph edge. */
+ final Label successor;
+
+ /**
+ * The next edge in the list of outgoing edges of a basic block. See {@link Label#outgoingEdges}.
+ */
+ Edge nextEdge;
+
+ /**
+ * Constructs a new Edge.
+ *
+ * @param info see {@link #info}.
+ * @param successor see {@link #successor}.
+ * @param nextEdge see {@link #nextEdge}.
+ */
+ Edge(final int info, final Label successor, final Edge nextEdge) {
+ this.info = info;
+ this.successor = successor;
+ this.nextEdge = nextEdge;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/FieldVisitor.java b/asm/src/main/java/org/objectweb/asm/FieldVisitor.java
new file mode 100644
index 00000000..2893d9f5
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/FieldVisitor.java
@@ -0,0 +1,151 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java field. The methods of this class must be called in the following order:
+ * ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code
+ * visitEnd}.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class FieldVisitor {
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /** The field visitor to which this visitor must delegate method calls. May be {@literal null}. */
+ protected FieldVisitor fv;
+
+ /**
+ * Constructs a new {@link FieldVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected FieldVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link FieldVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be
+ * null.
+ */
+ protected FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.fv = fieldVisitor;
+ }
+
+ /**
+ * The field visitor to which this visitor must delegate method calls. May be {@literal null}.
+ *
+ * @return the field visitor to which this visitor must delegate method calls, or {@literal null}.
+ */
+ public FieldVisitor getDelegate() {
+ return fv;
+ }
+
+ /**
+ * Visits an annotation of the field.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (fv != null) {
+ return fv.visitAnnotation(descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on the type of the field.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#FIELD}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException("This feature requires ASM5");
+ }
+ if (fv != null) {
+ return fv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a non standard attribute of the field.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ if (fv != null) {
+ fv.visitAttribute(attribute);
+ }
+ }
+
+ /**
+ * Visits the end of the field. This method, which is the last one to be called, is used to inform
+ * the visitor that all the annotations and attributes of the field have been visited.
+ */
+ public void visitEnd() {
+ if (fv != null) {
+ fv.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/FieldWriter.java b/asm/src/main/java/org/objectweb/asm/FieldWriter.java
new file mode 100644
index 00000000..b0c4502b
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/FieldWriter.java
@@ -0,0 +1,284 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A {@link FieldVisitor} that generates a corresponding 'field_info' structure, as defined in the
+ * Java Virtual Machine Specification (JVMS).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5">JVMS
+ * 4.5</a>
+ * @author Eric Bruneton
+ */
+final class FieldWriter extends FieldVisitor {
+
+ /** Where the constants used in this FieldWriter must be stored. */
+ private final SymbolTable symbolTable;
+
+ // Note: fields are ordered as in the field_info structure, and those related to attributes are
+ // ordered as in Section 4.7 of the JVMS.
+
+ /**
+ * The access_flags field of the field_info JVMS structure. This field can contain ASM specific
+ * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the
+ * ClassFile structure.
+ */
+ private final int accessFlags;
+
+ /** The name_index field of the field_info JVMS structure. */
+ private final int nameIndex;
+
+ /** The descriptor_index field of the field_info JVMS structure. */
+ private final int descriptorIndex;
+
+ /**
+ * The signature_index field of the Signature attribute of this field_info, or 0 if there is no
+ * Signature attribute.
+ */
+ private int signatureIndex;
+
+ /**
+ * The constantvalue_index field of the ConstantValue attribute of this field_info, or 0 if there
+ * is no ConstantValue attribute.
+ */
+ private int constantValueIndex;
+
+ /**
+ * The last runtime visible annotation of this field. The previous ones can be accessed with the
+ * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleAnnotation;
+
+ /**
+ * The last runtime invisible annotation of this field. The previous ones can be accessed with the
+ * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleAnnotation;
+
+ /**
+ * The last runtime visible type annotation of this field. The previous ones can be accessed with
+ * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
+
+ /**
+ * The last runtime invisible type annotation of this field. The previous ones can be accessed
+ * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
+
+ /**
+ * The first non standard attribute of this field. The next ones can be accessed with the {@link
+ * Attribute#nextAttribute} field. May be {@literal null}.
+ *
+ * <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
+ * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
+ * #putFieldInfo} method writes the attributes in the order defined by this list, i.e. in the
+ * reverse order specified by the user.
+ */
+ private Attribute firstAttribute;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link FieldWriter}.
+ *
+ * @param symbolTable where the constants used in this FieldWriter must be stored.
+ * @param access the field's access flags (see {@link Opcodes}).
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link Type}).
+ * @param signature the field's signature. May be {@literal null}.
+ * @param constantValue the field's constant value. May be {@literal null}.
+ */
+ FieldWriter(
+ final SymbolTable symbolTable,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object constantValue) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.symbolTable = symbolTable;
+ this.accessFlags = access;
+ this.nameIndex = symbolTable.addConstantUtf8(name);
+ this.descriptorIndex = symbolTable.addConstantUtf8(descriptor);
+ if (signature != null) {
+ this.signatureIndex = symbolTable.addConstantUtf8(signature);
+ }
+ if (constantValue != null) {
+ this.constantValueIndex = symbolTable.addConstant(constantValue).index;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the FieldVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeVisibleAnnotation);
+ } else {
+ return lastRuntimeInvisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeInvisibleAnnotation);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ // Store the attributes in the <i>reverse</i> order of their visit by this method.
+ attribute.nextAttribute = firstAttribute;
+ firstAttribute = attribute;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the size of the field_info JVMS structure generated by this FieldWriter. Also adds the
+ * names of the attributes of this field in the constant pool.
+ *
+ * @return the size in bytes of the field_info JVMS structure.
+ */
+ int computeFieldInfoSize() {
+ // The access_flags, name_index, descriptor_index and attributes_count fields use 8 bytes.
+ int size = 8;
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ if (constantValueIndex != 0) {
+ // ConstantValue attributes always use 8 bytes.
+ symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE);
+ size += 8;
+ }
+ size += Attribute.computeAttributesSize(symbolTable, accessFlags, signatureIndex);
+ size +=
+ AnnotationWriter.computeAnnotationsSize(
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation);
+ if (firstAttribute != null) {
+ size += firstAttribute.computeAttributesSize(symbolTable);
+ }
+ return size;
+ }
+
+ /**
+ * Puts the content of the field_info JVMS structure generated by this FieldWriter into the given
+ * ByteVector.
+ *
+ * @param output where the field_info structure must be put.
+ */
+ void putFieldInfo(final ByteVector output) {
+ boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5;
+ // Put the access_flags, name_index and descriptor_index fields.
+ int mask = useSyntheticAttribute ? Opcodes.ACC_SYNTHETIC : 0;
+ output.putShort(accessFlags & ~mask).putShort(nameIndex).putShort(descriptorIndex);
+ // Compute and put the attributes_count field.
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ int attributesCount = 0;
+ if (constantValueIndex != 0) {
+ ++attributesCount;
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
+ ++attributesCount;
+ }
+ if (signatureIndex != 0) {
+ ++attributesCount;
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ ++attributesCount;
+ }
+ if (lastRuntimeVisibleAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ ++attributesCount;
+ }
+ if (firstAttribute != null) {
+ attributesCount += firstAttribute.getAttributeCount();
+ }
+ output.putShort(attributesCount);
+ // Put the field_info attributes.
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ if (constantValueIndex != 0) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE))
+ .putInt(2)
+ .putShort(constantValueIndex);
+ }
+ Attribute.putAttributes(symbolTable, accessFlags, signatureIndex, output);
+ AnnotationWriter.putAnnotations(
+ symbolTable,
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation,
+ output);
+ if (firstAttribute != null) {
+ firstAttribute.putAttributes(symbolTable, output);
+ }
+ }
+
+ /**
+ * Collects the attributes of this field into the given set of attribute prototypes.
+ *
+ * @param attributePrototypes a set of attribute prototypes.
+ */
+ final void collectAttributePrototypes(final Attribute.Set attributePrototypes) {
+ attributePrototypes.addAttributes(firstAttribute);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Frame.java b/asm/src/main/java/org/objectweb/asm/Frame.java
new file mode 100644
index 00000000..07f256e5
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Frame.java
@@ -0,0 +1,1473 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * The input and output stack map frames of a basic block.
+ *
+ * <p>Stack map frames are computed in two steps:
+ *
+ * <ul>
+ * <li>During the visit of each instruction in MethodWriter, the state of the frame at the end of
+ * the current basic block is updated by simulating the action of the instruction on the
+ * previous state of this so called "output frame".
+ * <li>After all instructions have been visited, a fix point algorithm is used in MethodWriter to
+ * compute the "input frame" of each basic block (i.e. the stack map frame at the beginning of
+ * the basic block). See {@link MethodWriter#computeAllFrames}.
+ * </ul>
+ *
+ * <p>Output stack map frames are computed relatively to the input frame of the basic block, which
+ * is not yet known when output frames are computed. It is therefore necessary to be able to
+ * represent abstract types such as "the type at position x in the input frame locals" or "the type
+ * at position x from the top of the input frame stack" or even "the type at position x in the input
+ * frame, with y more (or less) array dimensions". This explains the rather complicated type format
+ * used in this class, explained below.
+ *
+ * <p>The local variables and the operand stack of input and output frames contain values called
+ * "abstract types" hereafter. An abstract type is represented with 4 fields named DIM, KIND, FLAGS
+ * and VALUE, packed in a single int value for better performance and memory efficiency:
+ *
+ * <pre>
+ * =====================================
+ * |...DIM|KIND|.F|...............VALUE|
+ * =====================================
+ * </pre>
+ *
+ * <ul>
+ * <li>the DIM field, stored in the 6 most significant bits, is a signed number of array
+ * dimensions (from -32 to 31, included). It can be retrieved with {@link #DIM_MASK} and a
+ * right shift of {@link #DIM_SHIFT}.
+ * <li>the KIND field, stored in 4 bits, indicates the kind of VALUE used. These 4 bits can be
+ * retrieved with {@link #KIND_MASK} and, without any shift, must be equal to {@link
+ * #CONSTANT_KIND}, {@link #REFERENCE_KIND}, {@link #UNINITIALIZED_KIND}, {@link #LOCAL_KIND}
+ * or {@link #STACK_KIND}.
+ * <li>the FLAGS field, stored in 2 bits, contains up to 2 boolean flags. Currently only one flag
+ * is defined, namely {@link #TOP_IF_LONG_OR_DOUBLE_FLAG}.
+ * <li>the VALUE field, stored in the remaining 20 bits, contains either
+ * <ul>
+ * <li>one of the constants {@link #ITEM_TOP}, {@link #ITEM_ASM_BOOLEAN}, {@link
+ * #ITEM_ASM_BYTE}, {@link #ITEM_ASM_CHAR} or {@link #ITEM_ASM_SHORT}, {@link
+ * #ITEM_INTEGER}, {@link #ITEM_FLOAT}, {@link #ITEM_LONG}, {@link #ITEM_DOUBLE}, {@link
+ * #ITEM_NULL} or {@link #ITEM_UNINITIALIZED_THIS}, if KIND is equal to {@link
+ * #CONSTANT_KIND}.
+ * <li>the index of a {@link Symbol#TYPE_TAG} {@link Symbol} in the type table of a {@link
+ * SymbolTable}, if KIND is equal to {@link #REFERENCE_KIND}.
+ * <li>the index of an {@link Symbol#UNINITIALIZED_TYPE_TAG} {@link Symbol} in the type
+ * table of a SymbolTable, if KIND is equal to {@link #UNINITIALIZED_KIND}.
+ * <li>the index of a local variable in the input stack frame, if KIND is equal to {@link
+ * #LOCAL_KIND}.
+ * <li>a position relatively to the top of the stack of the input stack frame, if KIND is
+ * equal to {@link #STACK_KIND},
+ * </ul>
+ * </ul>
+ *
+ * <p>Output frames can contain abstract types of any kind and with a positive or negative array
+ * dimension (and even unassigned types, represented by 0 - which does not correspond to any valid
+ * abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND or
+ * UNINITIALIZED_KIND abstract types of positive or {@literal null} array dimension. In all cases
+ * the type table contains only internal type names (array type descriptors are forbidden - array
+ * dimensions must be represented through the DIM field).
+ *
+ * <p>The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE +
+ * TOP), for local variables as well as in the operand stack. This is necessary to be able to
+ * simulate DUPx_y instructions, whose effect would be dependent on the concrete types represented
+ * by the abstract types in the stack (which are not always known).
+ *
+ * @author Eric Bruneton
+ */
+class Frame {
+
+ // Constants used in the StackMapTable attribute.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4.
+
+ static final int SAME_FRAME = 0;
+ static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64;
+ static final int RESERVED = 128;
+ static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247;
+ static final int CHOP_FRAME = 248;
+ static final int SAME_FRAME_EXTENDED = 251;
+ static final int APPEND_FRAME = 252;
+ static final int FULL_FRAME = 255;
+
+ static final int ITEM_TOP = 0;
+ static final int ITEM_INTEGER = 1;
+ static final int ITEM_FLOAT = 2;
+ static final int ITEM_DOUBLE = 3;
+ static final int ITEM_LONG = 4;
+ static final int ITEM_NULL = 5;
+ static final int ITEM_UNINITIALIZED_THIS = 6;
+ static final int ITEM_OBJECT = 7;
+ static final int ITEM_UNINITIALIZED = 8;
+ // Additional, ASM specific constants used in abstract types below.
+ private static final int ITEM_ASM_BOOLEAN = 9;
+ private static final int ITEM_ASM_BYTE = 10;
+ private static final int ITEM_ASM_CHAR = 11;
+ private static final int ITEM_ASM_SHORT = 12;
+
+ // The size and offset in bits of each field of an abstract type.
+
+ private static final int DIM_SIZE = 6;
+ private static final int KIND_SIZE = 4;
+ private static final int FLAGS_SIZE = 2;
+ private static final int VALUE_SIZE = 32 - DIM_SIZE - KIND_SIZE - FLAGS_SIZE;
+
+ private static final int DIM_SHIFT = KIND_SIZE + FLAGS_SIZE + VALUE_SIZE;
+ private static final int KIND_SHIFT = FLAGS_SIZE + VALUE_SIZE;
+ private static final int FLAGS_SHIFT = VALUE_SIZE;
+
+ // Bitmasks to get each field of an abstract type.
+
+ private static final int DIM_MASK = ((1 << DIM_SIZE) - 1) << DIM_SHIFT;
+ private static final int KIND_MASK = ((1 << KIND_SIZE) - 1) << KIND_SHIFT;
+ private static final int VALUE_MASK = (1 << VALUE_SIZE) - 1;
+
+ // Constants to manipulate the DIM field of an abstract type.
+
+ /** The constant to be added to an abstract type to get one with one more array dimension. */
+ private static final int ARRAY_OF = +1 << DIM_SHIFT;
+
+ /** The constant to be added to an abstract type to get one with one less array dimension. */
+ private static final int ELEMENT_OF = -1 << DIM_SHIFT;
+
+ // Possible values for the KIND field of an abstract type.
+
+ private static final int CONSTANT_KIND = 1 << KIND_SHIFT;
+ private static final int REFERENCE_KIND = 2 << KIND_SHIFT;
+ private static final int UNINITIALIZED_KIND = 3 << KIND_SHIFT;
+ private static final int LOCAL_KIND = 4 << KIND_SHIFT;
+ private static final int STACK_KIND = 5 << KIND_SHIFT;
+
+ // Possible flags for the FLAGS field of an abstract type.
+
+ /**
+ * A flag used for LOCAL_KIND and STACK_KIND abstract types, indicating that if the resolved,
+ * concrete type is LONG or DOUBLE, TOP should be used instead (because the value has been
+ * partially overridden with an xSTORE instruction).
+ */
+ private static final int TOP_IF_LONG_OR_DOUBLE_FLAG = 1 << FLAGS_SHIFT;
+
+ // Useful predefined abstract types (all the possible CONSTANT_KIND types).
+
+ private static final int TOP = CONSTANT_KIND | ITEM_TOP;
+ private static final int BOOLEAN = CONSTANT_KIND | ITEM_ASM_BOOLEAN;
+ private static final int BYTE = CONSTANT_KIND | ITEM_ASM_BYTE;
+ private static final int CHAR = CONSTANT_KIND | ITEM_ASM_CHAR;
+ private static final int SHORT = CONSTANT_KIND | ITEM_ASM_SHORT;
+ private static final int INTEGER = CONSTANT_KIND | ITEM_INTEGER;
+ private static final int FLOAT = CONSTANT_KIND | ITEM_FLOAT;
+ private static final int LONG = CONSTANT_KIND | ITEM_LONG;
+ private static final int DOUBLE = CONSTANT_KIND | ITEM_DOUBLE;
+ private static final int NULL = CONSTANT_KIND | ITEM_NULL;
+ private static final int UNINITIALIZED_THIS = CONSTANT_KIND | ITEM_UNINITIALIZED_THIS;
+
+ // -----------------------------------------------------------------------------------------------
+ // Instance fields
+ // -----------------------------------------------------------------------------------------------
+
+ /** The basic block to which these input and output stack map frames correspond. */
+ Label owner;
+
+ /** The input stack map frame locals. This is an array of abstract types. */
+ private int[] inputLocals;
+
+ /** The input stack map frame stack. This is an array of abstract types. */
+ private int[] inputStack;
+
+ /** The output stack map frame locals. This is an array of abstract types. */
+ private int[] outputLocals;
+
+ /** The output stack map frame stack. This is an array of abstract types. */
+ private int[] outputStack;
+
+ /**
+ * The start of the output stack, relatively to the input stack. This offset is always negative or
+ * null. A null offset means that the output stack must be appended to the input stack. A -n
+ * offset means that the first n output stack elements must replace the top n input stack
+ * elements, and that the other elements must be appended to the input stack.
+ */
+ private short outputStackStart;
+
+ /** The index of the top stack element in {@link #outputStack}. */
+ private short outputStackTop;
+
+ /** The number of types that are initialized in the basic block. See {@link #initializations}. */
+ private int initializationCount;
+
+ /**
+ * The abstract types that are initialized in the basic block. A constructor invocation on an
+ * UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace <i>every occurrence</i> of this
+ * type in the local variables and in the operand stack. This cannot be done during the first step
+ * of the algorithm since, during this step, the local variables and the operand stack types are
+ * still abstract. It is therefore necessary to store the abstract types of the constructors which
+ * are invoked in the basic block, in order to do this replacement during the second step of the
+ * algorithm, where the frames are fully computed. Note that this array can contain abstract types
+ * that are relative to the input locals or to the input stack.
+ */
+ private int[] initializations;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new Frame.
+ *
+ * @param owner the basic block to which these input and output stack map frames correspond.
+ */
+ Frame(final Label owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Sets this frame to the value of the given frame.
+ *
+ * <p>WARNING: after this method is called the two frames share the same data structures. It is
+ * recommended to discard the given frame to avoid unexpected side effects.
+ *
+ * @param frame The new frame value.
+ */
+ final void copyFrom(final Frame frame) {
+ inputLocals = frame.inputLocals;
+ inputStack = frame.inputStack;
+ outputStackStart = 0;
+ outputLocals = frame.outputLocals;
+ outputStack = frame.outputStack;
+ outputStackTop = frame.outputStackTop;
+ initializationCount = frame.initializationCount;
+ initializations = frame.initializations;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Static methods to get abstract types from other type formats
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the abstract type corresponding to the given public API frame element type.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param type a frame element type described using the same format as in {@link
+ * MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
+ * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or
+ * {@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating
+ * a NEW instruction (for uninitialized types).
+ * @return the abstract type corresponding to the given frame element type.
+ */
+ static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Object type) {
+ if (type instanceof Integer) {
+ return CONSTANT_KIND | ((Integer) type).intValue();
+ } else if (type instanceof String) {
+ String descriptor = Type.getObjectType((String) type).getDescriptor();
+ return getAbstractTypeFromDescriptor(symbolTable, descriptor, 0);
+ } else {
+ return UNINITIALIZED_KIND
+ | symbolTable.addUninitializedType("", ((Label) type).bytecodeOffset);
+ }
+ }
+
+ /**
+ * Returns the abstract type corresponding to the internal name of a class.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param internalName the internal name of a class. This must <i>not</i> be an array type
+ * descriptor.
+ * @return the abstract type value corresponding to the given internal name.
+ */
+ static int getAbstractTypeFromInternalName(
+ final SymbolTable symbolTable, final String internalName) {
+ return REFERENCE_KIND | symbolTable.addType(internalName);
+ }
+
+ /**
+ * Returns the abstract type corresponding to the given type descriptor.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param buffer a string ending with a type descriptor.
+ * @param offset the start offset of the type descriptor in buffer.
+ * @return the abstract type corresponding to the given type descriptor.
+ */
+ private static int getAbstractTypeFromDescriptor(
+ final SymbolTable symbolTable, final String buffer, final int offset) {
+ String internalName;
+ switch (buffer.charAt(offset)) {
+ case 'V':
+ return 0;
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ return INTEGER;
+ case 'F':
+ return FLOAT;
+ case 'J':
+ return LONG;
+ case 'D':
+ return DOUBLE;
+ case 'L':
+ internalName = buffer.substring(offset + 1, buffer.length() - 1);
+ return REFERENCE_KIND | symbolTable.addType(internalName);
+ case '[':
+ int elementDescriptorOffset = offset + 1;
+ while (buffer.charAt(elementDescriptorOffset) == '[') {
+ ++elementDescriptorOffset;
+ }
+ int typeValue;
+ switch (buffer.charAt(elementDescriptorOffset)) {
+ case 'Z':
+ typeValue = BOOLEAN;
+ break;
+ case 'C':
+ typeValue = CHAR;
+ break;
+ case 'B':
+ typeValue = BYTE;
+ break;
+ case 'S':
+ typeValue = SHORT;
+ break;
+ case 'I':
+ typeValue = INTEGER;
+ break;
+ case 'F':
+ typeValue = FLOAT;
+ break;
+ case 'J':
+ typeValue = LONG;
+ break;
+ case 'D':
+ typeValue = DOUBLE;
+ break;
+ case 'L':
+ internalName = buffer.substring(elementDescriptorOffset + 1, buffer.length() - 1);
+ typeValue = REFERENCE_KIND | symbolTable.addType(internalName);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods related to the input frame
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Sets the input frame from the given method description. This method is used to initialize the
+ * first frame of a method, which is implicit (i.e. not stored explicitly in the StackMapTable
+ * attribute).
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param access the method's access flags.
+ * @param descriptor the method descriptor.
+ * @param maxLocals the maximum number of local variables of the method.
+ */
+ final void setInputFrameFromDescriptor(
+ final SymbolTable symbolTable,
+ final int access,
+ final String descriptor,
+ final int maxLocals) {
+ inputLocals = new int[maxLocals];
+ inputStack = new int[0];
+ int inputLocalIndex = 0;
+ if ((access & Opcodes.ACC_STATIC) == 0) {
+ if ((access & Constants.ACC_CONSTRUCTOR) == 0) {
+ inputLocals[inputLocalIndex++] =
+ REFERENCE_KIND | symbolTable.addType(symbolTable.getClassName());
+ } else {
+ inputLocals[inputLocalIndex++] = UNINITIALIZED_THIS;
+ }
+ }
+ for (Type argumentType : Type.getArgumentTypes(descriptor)) {
+ int abstractType =
+ getAbstractTypeFromDescriptor(symbolTable, argumentType.getDescriptor(), 0);
+ inputLocals[inputLocalIndex++] = abstractType;
+ if (abstractType == LONG || abstractType == DOUBLE) {
+ inputLocals[inputLocalIndex++] = TOP;
+ }
+ }
+ while (inputLocalIndex < maxLocals) {
+ inputLocals[inputLocalIndex++] = TOP;
+ }
+ }
+
+ /**
+ * Sets the input frame from the given public API frame description.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param numLocal the number of local variables.
+ * @param local the local variable types, described using the same format as in {@link
+ * MethodVisitor#visitFrame}.
+ * @param numStack the number of operand stack elements.
+ * @param stack the operand stack types, described using the same format as in {@link
+ * MethodVisitor#visitFrame}.
+ */
+ final void setInputFrameFromApiFormat(
+ final SymbolTable symbolTable,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ int inputLocalIndex = 0;
+ for (int i = 0; i < numLocal; ++i) {
+ inputLocals[inputLocalIndex++] = getAbstractTypeFromApiFormat(symbolTable, local[i]);
+ if (local[i] == Opcodes.LONG || local[i] == Opcodes.DOUBLE) {
+ inputLocals[inputLocalIndex++] = TOP;
+ }
+ }
+ while (inputLocalIndex < inputLocals.length) {
+ inputLocals[inputLocalIndex++] = TOP;
+ }
+ int numStackTop = 0;
+ for (int i = 0; i < numStack; ++i) {
+ if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
+ ++numStackTop;
+ }
+ }
+ inputStack = new int[numStack + numStackTop];
+ int inputStackIndex = 0;
+ for (int i = 0; i < numStack; ++i) {
+ inputStack[inputStackIndex++] = getAbstractTypeFromApiFormat(symbolTable, stack[i]);
+ if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
+ inputStack[inputStackIndex++] = TOP;
+ }
+ }
+ outputStackTop = 0;
+ initializationCount = 0;
+ }
+
+ final int getInputStackSize() {
+ return inputStack.length;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods related to the output frame
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the abstract type stored at the given local variable index in the output frame.
+ *
+ * @param localIndex the index of the local variable whose value must be returned.
+ * @return the abstract type stored at the given local variable index in the output frame.
+ */
+ private int getLocal(final int localIndex) {
+ if (outputLocals == null || localIndex >= outputLocals.length) {
+ // If this local has never been assigned in this basic block, it is still equal to its value
+ // in the input frame.
+ return LOCAL_KIND | localIndex;
+ } else {
+ int abstractType = outputLocals[localIndex];
+ if (abstractType == 0) {
+ // If this local has never been assigned in this basic block, so it is still equal to its
+ // value in the input frame.
+ abstractType = outputLocals[localIndex] = LOCAL_KIND | localIndex;
+ }
+ return abstractType;
+ }
+ }
+
+ /**
+ * Replaces the abstract type stored at the given local variable index in the output frame.
+ *
+ * @param localIndex the index of the output frame local variable that must be set.
+ * @param abstractType the value that must be set.
+ */
+ private void setLocal(final int localIndex, final int abstractType) {
+ // Create and/or resize the output local variables array if necessary.
+ if (outputLocals == null) {
+ outputLocals = new int[10];
+ }
+ int outputLocalsLength = outputLocals.length;
+ if (localIndex >= outputLocalsLength) {
+ int[] newOutputLocals = new int[Math.max(localIndex + 1, 2 * outputLocalsLength)];
+ System.arraycopy(outputLocals, 0, newOutputLocals, 0, outputLocalsLength);
+ outputLocals = newOutputLocals;
+ }
+ // Set the local variable.
+ outputLocals[localIndex] = abstractType;
+ }
+
+ /**
+ * Pushes the given abstract type on the output frame stack.
+ *
+ * @param abstractType an abstract type.
+ */
+ private void push(final int abstractType) {
+ // Create and/or resize the output stack array if necessary.
+ if (outputStack == null) {
+ outputStack = new int[10];
+ }
+ int outputStackLength = outputStack.length;
+ if (outputStackTop >= outputStackLength) {
+ int[] newOutputStack = new int[Math.max(outputStackTop + 1, 2 * outputStackLength)];
+ System.arraycopy(outputStack, 0, newOutputStack, 0, outputStackLength);
+ outputStack = newOutputStack;
+ }
+ // Pushes the abstract type on the output stack.
+ outputStack[outputStackTop++] = abstractType;
+ // Updates the maximum size reached by the output stack, if needed (note that this size is
+ // relative to the input stack size, which is not known yet).
+ short outputStackSize = (short) (outputStackStart + outputStackTop);
+ if (outputStackSize > owner.outputStackMax) {
+ owner.outputStackMax = outputStackSize;
+ }
+ }
+
+ /**
+ * Pushes the abstract type corresponding to the given descriptor on the output frame stack.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param descriptor a type or method descriptor (in which case its return type is pushed).
+ */
+ private void push(final SymbolTable symbolTable, final String descriptor) {
+ int typeDescriptorOffset =
+ descriptor.charAt(0) == '(' ? Type.getReturnTypeOffset(descriptor) : 0;
+ int abstractType = getAbstractTypeFromDescriptor(symbolTable, descriptor, typeDescriptorOffset);
+ if (abstractType != 0) {
+ push(abstractType);
+ if (abstractType == LONG || abstractType == DOUBLE) {
+ push(TOP);
+ }
+ }
+ }
+
+ /**
+ * Pops an abstract type from the output frame stack and returns its value.
+ *
+ * @return the abstract type that has been popped from the output frame stack.
+ */
+ private int pop() {
+ if (outputStackTop > 0) {
+ return outputStack[--outputStackTop];
+ } else {
+ // If the output frame stack is empty, pop from the input stack.
+ return STACK_KIND | -(--outputStackStart);
+ }
+ }
+
+ /**
+ * Pops the given number of abstract types from the output frame stack.
+ *
+ * @param elements the number of abstract types that must be popped.
+ */
+ private void pop(final int elements) {
+ if (outputStackTop >= elements) {
+ outputStackTop -= elements;
+ } else {
+ // If the number of elements to be popped is greater than the number of elements in the output
+ // stack, clear it, and pop the remaining elements from the input stack.
+ outputStackStart -= elements - outputStackTop;
+ outputStackTop = 0;
+ }
+ }
+
+ /**
+ * Pops as many abstract types from the output frame stack as described by the given descriptor.
+ *
+ * @param descriptor a type or method descriptor (in which case its argument types are popped).
+ */
+ private void pop(final String descriptor) {
+ char firstDescriptorChar = descriptor.charAt(0);
+ if (firstDescriptorChar == '(') {
+ pop((Type.getArgumentsAndReturnSizes(descriptor) >> 2) - 1);
+ } else if (firstDescriptorChar == 'J' || firstDescriptorChar == 'D') {
+ pop(2);
+ } else {
+ pop(1);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to handle uninitialized types
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds an abstract type to the list of types on which a constructor is invoked in the basic
+ * block.
+ *
+ * @param abstractType an abstract type on a which a constructor is invoked.
+ */
+ private void addInitializedType(final int abstractType) {
+ // Create and/or resize the initializations array if necessary.
+ if (initializations == null) {
+ initializations = new int[2];
+ }
+ int initializationsLength = initializations.length;
+ if (initializationCount >= initializationsLength) {
+ int[] newInitializations =
+ new int[Math.max(initializationCount + 1, 2 * initializationsLength)];
+ System.arraycopy(initializations, 0, newInitializations, 0, initializationsLength);
+ initializations = newInitializations;
+ }
+ // Store the abstract type.
+ initializations[initializationCount++] = abstractType;
+ }
+
+ /**
+ * Returns the "initialized" abstract type corresponding to the given abstract type.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param abstractType an abstract type.
+ * @return the REFERENCE_KIND abstract type corresponding to abstractType if it is
+ * UNINITIALIZED_THIS or an UNINITIALIZED_KIND abstract type for one of the types on which a
+ * constructor is invoked in the basic block. Otherwise returns abstractType.
+ */
+ private int getInitializedType(final SymbolTable symbolTable, final int abstractType) {
+ if (abstractType == UNINITIALIZED_THIS
+ || (abstractType & (DIM_MASK | KIND_MASK)) == UNINITIALIZED_KIND) {
+ for (int i = 0; i < initializationCount; ++i) {
+ int initializedType = initializations[i];
+ int dim = initializedType & DIM_MASK;
+ int kind = initializedType & KIND_MASK;
+ int value = initializedType & VALUE_MASK;
+ if (kind == LOCAL_KIND) {
+ initializedType = dim + inputLocals[value];
+ } else if (kind == STACK_KIND) {
+ initializedType = dim + inputStack[inputStack.length - value];
+ }
+ if (abstractType == initializedType) {
+ if (abstractType == UNINITIALIZED_THIS) {
+ return REFERENCE_KIND | symbolTable.addType(symbolTable.getClassName());
+ } else {
+ return REFERENCE_KIND
+ | symbolTable.addType(symbolTable.getType(abstractType & VALUE_MASK).value);
+ }
+ }
+ }
+ }
+ return abstractType;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Main method, to simulate the execution of each instruction on the output frame
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Simulates the action of the given instruction on the output stack frame.
+ *
+ * @param opcode the opcode of the instruction.
+ * @param arg the numeric operand of the instruction, if any.
+ * @param argSymbol the Symbol operand of the instruction, if any.
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ */
+ void execute(
+ final int opcode, final int arg, final Symbol argSymbol, final SymbolTable symbolTable) {
+ // Abstract types popped from the stack or read from local variables.
+ int abstractType1;
+ int abstractType2;
+ int abstractType3;
+ int abstractType4;
+ switch (opcode) {
+ case Opcodes.NOP:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.GOTO:
+ case Opcodes.RETURN:
+ break;
+ case Opcodes.ACONST_NULL:
+ push(NULL);
+ break;
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ case Opcodes.ILOAD:
+ push(INTEGER);
+ break;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.LLOAD:
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.FLOAD:
+ push(FLOAT);
+ break;
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.DLOAD:
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LDC:
+ switch (argSymbol.tag) {
+ case Symbol.CONSTANT_INTEGER_TAG:
+ push(INTEGER);
+ break;
+ case Symbol.CONSTANT_LONG_TAG:
+ push(LONG);
+ push(TOP);
+ break;
+ case Symbol.CONSTANT_FLOAT_TAG:
+ push(FLOAT);
+ break;
+ case Symbol.CONSTANT_DOUBLE_TAG:
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Symbol.CONSTANT_CLASS_TAG:
+ push(REFERENCE_KIND | symbolTable.addType("java/lang/Class"));
+ break;
+ case Symbol.CONSTANT_STRING_TAG:
+ push(REFERENCE_KIND | symbolTable.addType("java/lang/String"));
+ break;
+ case Symbol.CONSTANT_METHOD_TYPE_TAG:
+ push(REFERENCE_KIND | symbolTable.addType("java/lang/invoke/MethodType"));
+ break;
+ case Symbol.CONSTANT_METHOD_HANDLE_TAG:
+ push(REFERENCE_KIND | symbolTable.addType("java/lang/invoke/MethodHandle"));
+ break;
+ case Symbol.CONSTANT_DYNAMIC_TAG:
+ push(symbolTable, argSymbol.value);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ break;
+ case Opcodes.ALOAD:
+ push(getLocal(arg));
+ break;
+ case Opcodes.LALOAD:
+ case Opcodes.D2L:
+ pop(2);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.DALOAD:
+ case Opcodes.L2D:
+ pop(2);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.AALOAD:
+ pop(1);
+ abstractType1 = pop();
+ push(abstractType1 == NULL ? abstractType1 : ELEMENT_OF + abstractType1);
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.ASTORE:
+ abstractType1 = pop();
+ setLocal(arg, abstractType1);
+ if (arg > 0) {
+ int previousLocalType = getLocal(arg - 1);
+ if (previousLocalType == LONG || previousLocalType == DOUBLE) {
+ setLocal(arg - 1, TOP);
+ } else if ((previousLocalType & KIND_MASK) == LOCAL_KIND
+ || (previousLocalType & KIND_MASK) == STACK_KIND) {
+ // The type of the previous local variable is not known yet, but if it later appears
+ // to be LONG or DOUBLE, we should then use TOP instead.
+ setLocal(arg - 1, previousLocalType | TOP_IF_LONG_OR_DOUBLE_FLAG);
+ }
+ }
+ break;
+ case Opcodes.LSTORE:
+ case Opcodes.DSTORE:
+ pop(1);
+ abstractType1 = pop();
+ setLocal(arg, abstractType1);
+ setLocal(arg + 1, TOP);
+ if (arg > 0) {
+ int previousLocalType = getLocal(arg - 1);
+ if (previousLocalType == LONG || previousLocalType == DOUBLE) {
+ setLocal(arg - 1, TOP);
+ } else if ((previousLocalType & KIND_MASK) == LOCAL_KIND
+ || (previousLocalType & KIND_MASK) == STACK_KIND) {
+ // The type of the previous local variable is not known yet, but if it later appears
+ // to be LONG or DOUBLE, we should then use TOP instead.
+ setLocal(arg - 1, previousLocalType | TOP_IF_LONG_OR_DOUBLE_FLAG);
+ }
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.AASTORE:
+ pop(3);
+ break;
+ case Opcodes.LASTORE:
+ case Opcodes.DASTORE:
+ pop(4);
+ break;
+ case Opcodes.POP:
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ pop(1);
+ break;
+ case Opcodes.POP2:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.LRETURN:
+ case Opcodes.DRETURN:
+ pop(2);
+ break;
+ case Opcodes.DUP:
+ abstractType1 = pop();
+ push(abstractType1);
+ push(abstractType1);
+ break;
+ case Opcodes.DUP_X1:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ push(abstractType1);
+ push(abstractType2);
+ push(abstractType1);
+ break;
+ case Opcodes.DUP_X2:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ abstractType3 = pop();
+ push(abstractType1);
+ push(abstractType3);
+ push(abstractType2);
+ push(abstractType1);
+ break;
+ case Opcodes.DUP2:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ push(abstractType2);
+ push(abstractType1);
+ push(abstractType2);
+ push(abstractType1);
+ break;
+ case Opcodes.DUP2_X1:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ abstractType3 = pop();
+ push(abstractType2);
+ push(abstractType1);
+ push(abstractType3);
+ push(abstractType2);
+ push(abstractType1);
+ break;
+ case Opcodes.DUP2_X2:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ abstractType3 = pop();
+ abstractType4 = pop();
+ push(abstractType2);
+ push(abstractType1);
+ push(abstractType4);
+ push(abstractType3);
+ push(abstractType2);
+ push(abstractType1);
+ break;
+ case Opcodes.SWAP:
+ abstractType1 = pop();
+ abstractType2 = pop();
+ push(abstractType1);
+ push(abstractType2);
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IADD:
+ case Opcodes.ISUB:
+ case Opcodes.IMUL:
+ case Opcodes.IDIV:
+ case Opcodes.IREM:
+ case Opcodes.IAND:
+ case Opcodes.IOR:
+ case Opcodes.IXOR:
+ case Opcodes.ISHL:
+ case Opcodes.ISHR:
+ case Opcodes.IUSHR:
+ case Opcodes.L2I:
+ case Opcodes.D2I:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ pop(2);
+ push(INTEGER);
+ break;
+ case Opcodes.LADD:
+ case Opcodes.LSUB:
+ case Opcodes.LMUL:
+ case Opcodes.LDIV:
+ case Opcodes.LREM:
+ case Opcodes.LAND:
+ case Opcodes.LOR:
+ case Opcodes.LXOR:
+ pop(4);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FALOAD:
+ case Opcodes.FADD:
+ case Opcodes.FSUB:
+ case Opcodes.FMUL:
+ case Opcodes.FDIV:
+ case Opcodes.FREM:
+ case Opcodes.L2F:
+ case Opcodes.D2F:
+ pop(2);
+ push(FLOAT);
+ break;
+ case Opcodes.DADD:
+ case Opcodes.DSUB:
+ case Opcodes.DMUL:
+ case Opcodes.DDIV:
+ case Opcodes.DREM:
+ pop(4);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LSHL:
+ case Opcodes.LSHR:
+ case Opcodes.LUSHR:
+ pop(3);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.IINC:
+ setLocal(arg, INTEGER);
+ break;
+ case Opcodes.I2L:
+ case Opcodes.F2L:
+ pop(1);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.I2F:
+ pop(1);
+ push(FLOAT);
+ break;
+ case Opcodes.I2D:
+ case Opcodes.F2D:
+ pop(1);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.F2I:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.INSTANCEOF:
+ pop(1);
+ push(INTEGER);
+ break;
+ case Opcodes.LCMP:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ pop(4);
+ push(INTEGER);
+ break;
+ case Opcodes.JSR:
+ case Opcodes.RET:
+ throw new IllegalArgumentException("JSR/RET are not supported with computeFrames option");
+ case Opcodes.GETSTATIC:
+ push(symbolTable, argSymbol.value);
+ break;
+ case Opcodes.PUTSTATIC:
+ pop(argSymbol.value);
+ break;
+ case Opcodes.GETFIELD:
+ pop(1);
+ push(symbolTable, argSymbol.value);
+ break;
+ case Opcodes.PUTFIELD:
+ pop(argSymbol.value);
+ pop();
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE:
+ pop(argSymbol.value);
+ if (opcode != Opcodes.INVOKESTATIC) {
+ abstractType1 = pop();
+ if (opcode == Opcodes.INVOKESPECIAL && argSymbol.name.charAt(0) == '<') {
+ addInitializedType(abstractType1);
+ }
+ }
+ push(symbolTable, argSymbol.value);
+ break;
+ case Opcodes.INVOKEDYNAMIC:
+ pop(argSymbol.value);
+ push(symbolTable, argSymbol.value);
+ break;
+ case Opcodes.NEW:
+ push(UNINITIALIZED_KIND | symbolTable.addUninitializedType(argSymbol.value, arg));
+ break;
+ case Opcodes.NEWARRAY:
+ pop();
+ switch (arg) {
+ case Opcodes.T_BOOLEAN:
+ push(ARRAY_OF | BOOLEAN);
+ break;
+ case Opcodes.T_CHAR:
+ push(ARRAY_OF | CHAR);
+ break;
+ case Opcodes.T_BYTE:
+ push(ARRAY_OF | BYTE);
+ break;
+ case Opcodes.T_SHORT:
+ push(ARRAY_OF | SHORT);
+ break;
+ case Opcodes.T_INT:
+ push(ARRAY_OF | INTEGER);
+ break;
+ case Opcodes.T_FLOAT:
+ push(ARRAY_OF | FLOAT);
+ break;
+ case Opcodes.T_DOUBLE:
+ push(ARRAY_OF | DOUBLE);
+ break;
+ case Opcodes.T_LONG:
+ push(ARRAY_OF | LONG);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ break;
+ case Opcodes.ANEWARRAY:
+ String arrayElementType = argSymbol.value;
+ pop();
+ if (arrayElementType.charAt(0) == '[') {
+ push(symbolTable, '[' + arrayElementType);
+ } else {
+ push(ARRAY_OF | REFERENCE_KIND | symbolTable.addType(arrayElementType));
+ }
+ break;
+ case Opcodes.CHECKCAST:
+ String castType = argSymbol.value;
+ pop();
+ if (castType.charAt(0) == '[') {
+ push(symbolTable, castType);
+ } else {
+ push(REFERENCE_KIND | symbolTable.addType(castType));
+ }
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ pop(arg);
+ push(symbolTable, argSymbol.value);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Frame merging methods, used in the second step of the stack map frame computation algorithm
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Computes the concrete output type corresponding to a given abstract output type.
+ *
+ * @param abstractOutputType an abstract output type.
+ * @param numStack the size of the input stack, used to resolve abstract output types of
+ * STACK_KIND kind.
+ * @return the concrete output type corresponding to 'abstractOutputType'.
+ */
+ private int getConcreteOutputType(final int abstractOutputType, final int numStack) {
+ int dim = abstractOutputType & DIM_MASK;
+ int kind = abstractOutputType & KIND_MASK;
+ if (kind == LOCAL_KIND) {
+ // By definition, a LOCAL_KIND type designates the concrete type of a local variable at
+ // the beginning of the basic block corresponding to this frame (which is known when
+ // this method is called, but was not when the abstract type was computed).
+ int concreteOutputType = dim + inputLocals[abstractOutputType & VALUE_MASK];
+ if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0
+ && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) {
+ concreteOutputType = TOP;
+ }
+ return concreteOutputType;
+ } else if (kind == STACK_KIND) {
+ // By definition, a STACK_KIND type designates the concrete type of a local variable at
+ // the beginning of the basic block corresponding to this frame (which is known when
+ // this method is called, but was not when the abstract type was computed).
+ int concreteOutputType = dim + inputStack[numStack - (abstractOutputType & VALUE_MASK)];
+ if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0
+ && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) {
+ concreteOutputType = TOP;
+ }
+ return concreteOutputType;
+ } else {
+ return abstractOutputType;
+ }
+ }
+
+ /**
+ * Merges the input frame of the given {@link Frame} with the input and output frames of this
+ * {@link Frame}. Returns {@literal true} if the given frame has been changed by this operation
+ * (the input and output frames of this {@link Frame} are never changed).
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param dstFrame the {@link Frame} whose input frame must be updated. This should be the frame
+ * of a successor, in the control flow graph, of the basic block corresponding to this frame.
+ * @param catchTypeIndex if 'frame' corresponds to an exception handler basic block, the type
+ * table index of the caught exception type, otherwise 0.
+ * @return {@literal true} if the input frame of 'frame' has been changed by this operation.
+ */
+ final boolean merge(
+ final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex) {
+ boolean frameChanged = false;
+
+ // Compute the concrete types of the local variables at the end of the basic block corresponding
+ // to this frame, by resolving its abstract output types, and merge these concrete types with
+ // those of the local variables in the input frame of dstFrame.
+ int numLocal = inputLocals.length;
+ int numStack = inputStack.length;
+ if (dstFrame.inputLocals == null) {
+ dstFrame.inputLocals = new int[numLocal];
+ frameChanged = true;
+ }
+ for (int i = 0; i < numLocal; ++i) {
+ int concreteOutputType;
+ if (outputLocals != null && i < outputLocals.length) {
+ int abstractOutputType = outputLocals[i];
+ if (abstractOutputType == 0) {
+ // If the local variable has never been assigned in this basic block, it is equal to its
+ // value at the beginning of the block.
+ concreteOutputType = inputLocals[i];
+ } else {
+ concreteOutputType = getConcreteOutputType(abstractOutputType, numStack);
+ }
+ } else {
+ // If the local variable has never been assigned in this basic block, it is equal to its
+ // value at the beginning of the block.
+ concreteOutputType = inputLocals[i];
+ }
+ // concreteOutputType might be an uninitialized type from the input locals or from the input
+ // stack. However, if a constructor has been called for this class type in the basic block,
+ // then this type is no longer uninitialized at the end of basic block.
+ if (initializations != null) {
+ concreteOutputType = getInitializedType(symbolTable, concreteOutputType);
+ }
+ frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputLocals, i);
+ }
+
+ // If dstFrame is an exception handler block, it can be reached from any instruction of the
+ // basic block corresponding to this frame, in particular from the first one. Therefore, the
+ // input locals of dstFrame should be compatible (i.e. merged) with the input locals of this
+ // frame (and the input stack of dstFrame should be compatible, i.e. merged, with a one
+ // element stack containing the caught exception type).
+ if (catchTypeIndex > 0) {
+ for (int i = 0; i < numLocal; ++i) {
+ frameChanged |= merge(symbolTable, inputLocals[i], dstFrame.inputLocals, i);
+ }
+ if (dstFrame.inputStack == null) {
+ dstFrame.inputStack = new int[1];
+ frameChanged = true;
+ }
+ frameChanged |= merge(symbolTable, catchTypeIndex, dstFrame.inputStack, 0);
+ return frameChanged;
+ }
+
+ // Compute the concrete types of the stack operands at the end of the basic block corresponding
+ // to this frame, by resolving its abstract output types, and merge these concrete types with
+ // those of the stack operands in the input frame of dstFrame.
+ int numInputStack = inputStack.length + outputStackStart;
+ if (dstFrame.inputStack == null) {
+ dstFrame.inputStack = new int[numInputStack + outputStackTop];
+ frameChanged = true;
+ }
+ // First, do this for the stack operands that have not been popped in the basic block
+ // corresponding to this frame, and which are therefore equal to their value in the input
+ // frame (except for uninitialized types, which may have been initialized).
+ for (int i = 0; i < numInputStack; ++i) {
+ int concreteOutputType = inputStack[i];
+ if (initializations != null) {
+ concreteOutputType = getInitializedType(symbolTable, concreteOutputType);
+ }
+ frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputStack, i);
+ }
+ // Then, do this for the stack operands that have pushed in the basic block (this code is the
+ // same as the one above for local variables).
+ for (int i = 0; i < outputStackTop; ++i) {
+ int abstractOutputType = outputStack[i];
+ int concreteOutputType = getConcreteOutputType(abstractOutputType, numStack);
+ if (initializations != null) {
+ concreteOutputType = getInitializedType(symbolTable, concreteOutputType);
+ }
+ frameChanged |=
+ merge(symbolTable, concreteOutputType, dstFrame.inputStack, numInputStack + i);
+ }
+ return frameChanged;
+ }
+
+ /**
+ * Merges the type at the given index in the given abstract type array with the given type.
+ * Returns {@literal true} if the type array has been modified by this operation.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param sourceType the abstract type with which the abstract type array element must be merged.
+ * This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link
+ * #UNINITIALIZED_KIND} kind, with positive or {@literal null} array dimensions.
+ * @param dstTypes an array of abstract types. These types should be of {@link #CONSTANT_KIND},
+ * {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or {@literal
+ * null} array dimensions.
+ * @param dstIndex the index of the type that must be merged in dstTypes.
+ * @return {@literal true} if the type array has been modified by this operation.
+ */
+ private static boolean merge(
+ final SymbolTable symbolTable,
+ final int sourceType,
+ final int[] dstTypes,
+ final int dstIndex) {
+ int dstType = dstTypes[dstIndex];
+ if (dstType == sourceType) {
+ // If the types are equal, merge(sourceType, dstType) = dstType, so there is no change.
+ return false;
+ }
+ int srcType = sourceType;
+ if ((sourceType & ~DIM_MASK) == NULL) {
+ if (dstType == NULL) {
+ return false;
+ }
+ srcType = NULL;
+ }
+ if (dstType == 0) {
+ // If dstTypes[dstIndex] has never been assigned, merge(srcType, dstType) = srcType.
+ dstTypes[dstIndex] = srcType;
+ return true;
+ }
+ int mergedType;
+ if ((dstType & DIM_MASK) != 0 || (dstType & KIND_MASK) == REFERENCE_KIND) {
+ // If dstType is a reference type of any array dimension.
+ if (srcType == NULL) {
+ // If srcType is the NULL type, merge(srcType, dstType) = dstType, so there is no change.
+ return false;
+ } else if ((srcType & (DIM_MASK | KIND_MASK)) == (dstType & (DIM_MASK | KIND_MASK))) {
+ // If srcType has the same array dimension and the same kind as dstType.
+ if ((dstType & KIND_MASK) == REFERENCE_KIND) {
+ // If srcType and dstType are reference types with the same array dimension,
+ // merge(srcType, dstType) = dim(srcType) | common super class of srcType and dstType.
+ mergedType =
+ (srcType & DIM_MASK)
+ | REFERENCE_KIND
+ | symbolTable.addMergedType(srcType & VALUE_MASK, dstType & VALUE_MASK);
+ } else {
+ // If srcType and dstType are array types of equal dimension but different element types,
+ // merge(srcType, dstType) = dim(srcType) - 1 | java/lang/Object.
+ int mergedDim = ELEMENT_OF + (srcType & DIM_MASK);
+ mergedType = mergedDim | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
+ }
+ } else if ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND) {
+ // If srcType is any other reference or array type,
+ // merge(srcType, dstType) = min(srcDdim, dstDim) | java/lang/Object
+ // where srcDim is the array dimension of srcType, minus 1 if srcType is an array type
+ // with a non reference element type (and similarly for dstDim).
+ int srcDim = srcType & DIM_MASK;
+ if (srcDim != 0 && (srcType & KIND_MASK) != REFERENCE_KIND) {
+ srcDim = ELEMENT_OF + srcDim;
+ }
+ int dstDim = dstType & DIM_MASK;
+ if (dstDim != 0 && (dstType & KIND_MASK) != REFERENCE_KIND) {
+ dstDim = ELEMENT_OF + dstDim;
+ }
+ mergedType =
+ Math.min(srcDim, dstDim) | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
+ } else {
+ // If srcType is any other type, merge(srcType, dstType) = TOP.
+ mergedType = TOP;
+ }
+ } else if (dstType == NULL) {
+ // If dstType is the NULL type, merge(srcType, dstType) = srcType, or TOP if srcType is not a
+ // an array type or a reference type.
+ mergedType =
+ (srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND ? srcType : TOP;
+ } else {
+ // If dstType is any other type, merge(srcType, dstType) = TOP whatever srcType.
+ mergedType = TOP;
+ }
+ if (mergedType != dstType) {
+ dstTypes[dstIndex] = mergedType;
+ return true;
+ }
+ return false;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Frame output methods, to generate StackMapFrame attributes
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Makes the given {@link MethodWriter} visit the input frame of this {@link Frame}. The visit is
+ * done with the {@link MethodWriter#visitFrameStart}, {@link MethodWriter#visitAbstractType} and
+ * {@link MethodWriter#visitFrameEnd} methods.
+ *
+ * @param methodWriter the {@link MethodWriter} that should visit the input frame of this {@link
+ * Frame}.
+ */
+ final void accept(final MethodWriter methodWriter) {
+ // Compute the number of locals, ignoring TOP types that are just after a LONG or a DOUBLE, and
+ // all trailing TOP types.
+ int[] localTypes = inputLocals;
+ int numLocal = 0;
+ int numTrailingTop = 0;
+ int i = 0;
+ while (i < localTypes.length) {
+ int localType = localTypes[i];
+ i += (localType == LONG || localType == DOUBLE) ? 2 : 1;
+ if (localType == TOP) {
+ numTrailingTop++;
+ } else {
+ numLocal += numTrailingTop + 1;
+ numTrailingTop = 0;
+ }
+ }
+ // Compute the stack size, ignoring TOP types that are just after a LONG or a DOUBLE.
+ int[] stackTypes = inputStack;
+ int numStack = 0;
+ i = 0;
+ while (i < stackTypes.length) {
+ int stackType = stackTypes[i];
+ i += (stackType == LONG || stackType == DOUBLE) ? 2 : 1;
+ numStack++;
+ }
+ // Visit the frame and its content.
+ int frameIndex = methodWriter.visitFrameStart(owner.bytecodeOffset, numLocal, numStack);
+ i = 0;
+ while (numLocal-- > 0) {
+ int localType = localTypes[i];
+ i += (localType == LONG || localType == DOUBLE) ? 2 : 1;
+ methodWriter.visitAbstractType(frameIndex++, localType);
+ }
+ i = 0;
+ while (numStack-- > 0) {
+ int stackType = stackTypes[i];
+ i += (stackType == LONG || stackType == DOUBLE) ? 2 : 1;
+ methodWriter.visitAbstractType(frameIndex++, stackType);
+ }
+ methodWriter.visitFrameEnd();
+ }
+
+ /**
+ * Put the given abstract type in the given ByteVector, using the JVMS verification_type_info
+ * format used in StackMapTable attributes.
+ *
+ * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
+ * @param abstractType an abstract type, restricted to {@link Frame#CONSTANT_KIND}, {@link
+ * Frame#REFERENCE_KIND} or {@link Frame#UNINITIALIZED_KIND} types.
+ * @param output where the abstract type must be put.
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4">JVMS
+ * 4.7.4</a>
+ */
+ static void putAbstractType(
+ final SymbolTable symbolTable, final int abstractType, final ByteVector output) {
+ int arrayDimensions = (abstractType & Frame.DIM_MASK) >> DIM_SHIFT;
+ if (arrayDimensions == 0) {
+ int typeValue = abstractType & VALUE_MASK;
+ switch (abstractType & KIND_MASK) {
+ case CONSTANT_KIND:
+ output.putByte(typeValue);
+ break;
+ case REFERENCE_KIND:
+ output
+ .putByte(ITEM_OBJECT)
+ .putShort(symbolTable.addConstantClass(symbolTable.getType(typeValue).value).index);
+ break;
+ case UNINITIALIZED_KIND:
+ output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ } else {
+ // Case of an array type, we need to build its descriptor first.
+ StringBuilder typeDescriptor = new StringBuilder();
+ while (arrayDimensions-- > 0) {
+ typeDescriptor.append('[');
+ }
+ if ((abstractType & KIND_MASK) == REFERENCE_KIND) {
+ typeDescriptor
+ .append('L')
+ .append(symbolTable.getType(abstractType & VALUE_MASK).value)
+ .append(';');
+ } else {
+ switch (abstractType & VALUE_MASK) {
+ case Frame.ITEM_ASM_BOOLEAN:
+ typeDescriptor.append('Z');
+ break;
+ case Frame.ITEM_ASM_BYTE:
+ typeDescriptor.append('B');
+ break;
+ case Frame.ITEM_ASM_CHAR:
+ typeDescriptor.append('C');
+ break;
+ case Frame.ITEM_ASM_SHORT:
+ typeDescriptor.append('S');
+ break;
+ case Frame.ITEM_INTEGER:
+ typeDescriptor.append('I');
+ break;
+ case Frame.ITEM_FLOAT:
+ typeDescriptor.append('F');
+ break;
+ case Frame.ITEM_LONG:
+ typeDescriptor.append('J');
+ break;
+ case Frame.ITEM_DOUBLE:
+ typeDescriptor.append('D');
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+ output
+ .putByte(ITEM_OBJECT)
+ .putShort(symbolTable.addConstantClass(typeDescriptor.toString()).index);
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Handle.java b/asm/src/main/java/org/objectweb/asm/Handle.java
new file mode 100644
index 00000000..6ffae75b
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Handle.java
@@ -0,0 +1,190 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm;
+
+/**
+ * A reference to a field or a method.
+ *
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+public final class Handle {
+
+ /**
+ * The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link
+ * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ */
+ private final int tag;
+
+ /** The internal name of the class that owns the field or method designated by this handle. */
+ private final String owner;
+
+ /** The name of the field or method designated by this handle. */
+ private final String name;
+
+ /** The descriptor of the field or method designated by this handle. */
+ private final String descriptor;
+
+ /** Whether the owner is an interface or not. */
+ private final boolean isInterface;
+
+ /**
+ * Constructs a new field or method handle.
+ *
+ * @param tag the kind of field or method designated by this Handle. Must be {@link
+ * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link
+ * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link
+ * Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of the class that owns the field or method designated by this
+ * handle (see {@link Type#getInternalName()}).
+ * @param name the name of the field or method designated by this handle.
+ * @param descriptor the descriptor of the field or method designated by this handle.
+ * @deprecated this constructor has been superseded by {@link #Handle(int, String, String, String,
+ * boolean)}.
+ */
+ @Deprecated
+ public Handle(final int tag, final String owner, final String name, final String descriptor) {
+ this(tag, owner, name, descriptor, tag == Opcodes.H_INVOKEINTERFACE);
+ }
+
+ /**
+ * Constructs a new field or method handle.
+ *
+ * @param tag the kind of field or method designated by this Handle. Must be {@link
+ * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link
+ * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link
+ * Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of the class that owns the field or method designated by this
+ * handle (see {@link Type#getInternalName()}).
+ * @param name the name of the field or method designated by this handle.
+ * @param descriptor the descriptor of the field or method designated by this handle.
+ * @param isInterface whether the owner is an interface or not.
+ */
+ public Handle(
+ final int tag,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ this.tag = tag;
+ this.owner = owner;
+ this.name = name;
+ this.descriptor = descriptor;
+ this.isInterface = isInterface;
+ }
+
+ /**
+ * Returns the kind of field or method designated by this handle.
+ *
+ * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link
+ * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link
+ * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ */
+ public int getTag() {
+ return tag;
+ }
+
+ /**
+ * Returns the internal name of the class that owns the field or method designated by this handle.
+ *
+ * @return the internal name of the class that owns the field or method designated by this handle
+ * (see {@link Type#getInternalName()}).
+ */
+ public String getOwner() {
+ return owner;
+ }
+
+ /**
+ * Returns the name of the field or method designated by this handle.
+ *
+ * @return the name of the field or method designated by this handle.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the descriptor of the field or method designated by this handle.
+ *
+ * @return the descriptor of the field or method designated by this handle.
+ */
+ public String getDesc() {
+ return descriptor;
+ }
+
+ /**
+ * Returns true if the owner of the field or method designated by this handle is an interface.
+ *
+ * @return true if the owner of the field or method designated by this handle is an interface.
+ */
+ public boolean isInterface() {
+ return isInterface;
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (!(object instanceof Handle)) {
+ return false;
+ }
+ Handle handle = (Handle) object;
+ return tag == handle.tag
+ && isInterface == handle.isInterface
+ && owner.equals(handle.owner)
+ && name.equals(handle.name)
+ && descriptor.equals(handle.descriptor);
+ }
+
+ @Override
+ public int hashCode() {
+ return tag
+ + (isInterface ? 64 : 0)
+ + owner.hashCode() * name.hashCode() * descriptor.hashCode();
+ }
+
+ /**
+ * Returns the textual representation of this handle. The textual representation is:
+ *
+ * <ul>
+ * <li>for a reference to a class: owner "." name descriptor " (" tag ")",
+ * <li>for a reference to an interface: owner "." name descriptor " (" tag " itf)".
+ * </ul>
+ */
+ @Override
+ public String toString() {
+ return owner + '.' + name + descriptor + " (" + tag + (isInterface ? " itf" : "") + ')';
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Handler.java b/asm/src/main/java/org/objectweb/asm/Handler.java
new file mode 100644
index 00000000..21593b65
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Handler.java
@@ -0,0 +1,198 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * Information about an exception handler. Corresponds to an element of the exception_table array of
+ * a Code attribute, as defined in the Java Virtual Machine Specification (JVMS). Handler instances
+ * can be chained together, with their {@link #nextHandler} field, to describe a full JVMS
+ * exception_table array.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.3">JVMS
+ * 4.7.3</a>
+ * @author Eric Bruneton
+ */
+final class Handler {
+
+ /**
+ * The start_pc field of this JVMS exception_table entry. Corresponds to the beginning of the
+ * exception handler's scope (inclusive).
+ */
+ final Label startPc;
+
+ /**
+ * The end_pc field of this JVMS exception_table entry. Corresponds to the end of the exception
+ * handler's scope (exclusive).
+ */
+ final Label endPc;
+
+ /**
+ * The handler_pc field of this JVMS exception_table entry. Corresponding to the beginning of the
+ * exception handler's code.
+ */
+ final Label handlerPc;
+
+ /**
+ * The catch_type field of this JVMS exception_table entry. This is the constant pool index of the
+ * internal name of the type of exceptions handled by this handler, or 0 to catch any exceptions.
+ */
+ final int catchType;
+
+ /**
+ * The internal name of the type of exceptions handled by this handler, or {@literal null} to
+ * catch any exceptions.
+ */
+ final String catchTypeDescriptor;
+
+ /** The next exception handler. */
+ Handler nextHandler;
+
+ /**
+ * Constructs a new Handler.
+ *
+ * @param startPc the start_pc field of this JVMS exception_table entry.
+ * @param endPc the end_pc field of this JVMS exception_table entry.
+ * @param handlerPc the handler_pc field of this JVMS exception_table entry.
+ * @param catchType The catch_type field of this JVMS exception_table entry.
+ * @param catchTypeDescriptor The internal name of the type of exceptions handled by this handler,
+ * or {@literal null} to catch any exceptions.
+ */
+ Handler(
+ final Label startPc,
+ final Label endPc,
+ final Label handlerPc,
+ final int catchType,
+ final String catchTypeDescriptor) {
+ this.startPc = startPc;
+ this.endPc = endPc;
+ this.handlerPc = handlerPc;
+ this.catchType = catchType;
+ this.catchTypeDescriptor = catchTypeDescriptor;
+ }
+
+ /**
+ * Constructs a new Handler from the given one, with a different scope.
+ *
+ * @param handler an existing Handler.
+ * @param startPc the start_pc field of this JVMS exception_table entry.
+ * @param endPc the end_pc field of this JVMS exception_table entry.
+ */
+ Handler(final Handler handler, final Label startPc, final Label endPc) {
+ this(startPc, endPc, handler.handlerPc, handler.catchType, handler.catchTypeDescriptor);
+ this.nextHandler = handler.nextHandler;
+ }
+
+ /**
+ * Removes the range between start and end from the Handler list that begins with the given
+ * element.
+ *
+ * @param firstHandler the beginning of a Handler list. May be {@literal null}.
+ * @param start the start of the range to be removed.
+ * @param end the end of the range to be removed. Maybe {@literal null}.
+ * @return the exception handler list with the start-end range removed.
+ */
+ static Handler removeRange(final Handler firstHandler, final Label start, final Label end) {
+ if (firstHandler == null) {
+ return null;
+ } else {
+ firstHandler.nextHandler = removeRange(firstHandler.nextHandler, start, end);
+ }
+ int handlerStart = firstHandler.startPc.bytecodeOffset;
+ int handlerEnd = firstHandler.endPc.bytecodeOffset;
+ int rangeStart = start.bytecodeOffset;
+ int rangeEnd = end == null ? Integer.MAX_VALUE : end.bytecodeOffset;
+ // Return early if [handlerStart,handlerEnd[ and [rangeStart,rangeEnd[ don't intersect.
+ if (rangeStart >= handlerEnd || rangeEnd <= handlerStart) {
+ return firstHandler;
+ }
+ if (rangeStart <= handlerStart) {
+ if (rangeEnd >= handlerEnd) {
+ // If [handlerStart,handlerEnd[ is included in [rangeStart,rangeEnd[, remove firstHandler.
+ return firstHandler.nextHandler;
+ } else {
+ // [handlerStart,handlerEnd[ - [rangeStart,rangeEnd[ = [rangeEnd,handlerEnd[
+ return new Handler(firstHandler, end, firstHandler.endPc);
+ }
+ } else if (rangeEnd >= handlerEnd) {
+ // [handlerStart,handlerEnd[ - [rangeStart,rangeEnd[ = [handlerStart,rangeStart[
+ return new Handler(firstHandler, firstHandler.startPc, start);
+ } else {
+ // [handlerStart,handlerEnd[ - [rangeStart,rangeEnd[ =
+ // [handlerStart,rangeStart[ + [rangeEnd,handerEnd[
+ firstHandler.nextHandler = new Handler(firstHandler, end, firstHandler.endPc);
+ return new Handler(firstHandler, firstHandler.startPc, start);
+ }
+ }
+
+ /**
+ * Returns the number of elements of the Handler list that begins with the given element.
+ *
+ * @param firstHandler the beginning of a Handler list. May be {@literal null}.
+ * @return the number of elements of the Handler list that begins with 'handler'.
+ */
+ static int getExceptionTableLength(final Handler firstHandler) {
+ int length = 0;
+ Handler handler = firstHandler;
+ while (handler != null) {
+ length++;
+ handler = handler.nextHandler;
+ }
+ return length;
+ }
+
+ /**
+ * Returns the size in bytes of the JVMS exception_table corresponding to the Handler list that
+ * begins with the given element. <i>This includes the exception_table_length field.</i>
+ *
+ * @param firstHandler the beginning of a Handler list. May be {@literal null}.
+ * @return the size in bytes of the exception_table_length and exception_table structures.
+ */
+ static int getExceptionTableSize(final Handler firstHandler) {
+ return 2 + 8 * getExceptionTableLength(firstHandler);
+ }
+
+ /**
+ * Puts the JVMS exception_table corresponding to the Handler list that begins with the given
+ * element. <i>This includes the exception_table_length field.</i>
+ *
+ * @param firstHandler the beginning of a Handler list. May be {@literal null}.
+ * @param output where the exception_table_length and exception_table structures must be put.
+ */
+ static void putExceptionTable(final Handler firstHandler, final ByteVector output) {
+ output.putShort(getExceptionTableLength(firstHandler));
+ Handler handler = firstHandler;
+ while (handler != null) {
+ output
+ .putShort(handler.startPc.bytecodeOffset)
+ .putShort(handler.endPc.bytecodeOffset)
+ .putShort(handler.handlerPc.bytecodeOffset)
+ .putShort(handler.catchType);
+ handler = handler.nextHandler;
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Label.java b/asm/src/main/java/org/objectweb/asm/Label.java
new file mode 100644
index 00000000..926f719e
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Label.java
@@ -0,0 +1,622 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A position in the bytecode of a method. Labels are used for jump, goto, and switch instructions,
+ * and for try catch blocks. A label designates the <i>instruction</i> that is just after. Note
+ * however that there can be other elements between a label and the instruction it designates (such
+ * as other labels, stack map frames, line numbers, etc.).
+ *
+ * @author Eric Bruneton
+ */
+public class Label {
+
+ /**
+ * A flag indicating that a label is only used for debug attributes. Such a label is not the start
+ * of a basic block, the target of a jump instruction, or an exception handler. It can be safely
+ * ignored in control flow graph analysis algorithms (for optimization purposes).
+ */
+ static final int FLAG_DEBUG_ONLY = 1;
+
+ /**
+ * A flag indicating that a label is the target of a jump instruction, or the start of an
+ * exception handler.
+ */
+ static final int FLAG_JUMP_TARGET = 2;
+
+ /** A flag indicating that the bytecode offset of a label is known. */
+ static final int FLAG_RESOLVED = 4;
+
+ /** A flag indicating that a label corresponds to a reachable basic block. */
+ static final int FLAG_REACHABLE = 8;
+
+ /**
+ * A flag indicating that the basic block corresponding to a label ends with a subroutine call. By
+ * construction in {@link MethodWriter#visitJumpInsn}, labels with this flag set have at least two
+ * outgoing edges:
+ *
+ * <ul>
+ * <li>the first one corresponds to the instruction that follows the jsr instruction in the
+ * bytecode, i.e. where execution continues when it returns from the jsr call. This is a
+ * virtual control flow edge, since execution never goes directly from the jsr to the next
+ * instruction. Instead, it goes to the subroutine and eventually returns to the instruction
+ * following the jsr. This virtual edge is used to compute the real outgoing edges of the
+ * basic blocks ending with a ret instruction, in {@link #addSubroutineRetSuccessors}.
+ * <li>the second one corresponds to the target of the jsr instruction,
+ * </ul>
+ */
+ static final int FLAG_SUBROUTINE_CALLER = 16;
+
+ /**
+ * A flag indicating that the basic block corresponding to a label is the start of a subroutine.
+ */
+ static final int FLAG_SUBROUTINE_START = 32;
+
+ /** A flag indicating that the basic block corresponding to a label is the end of a subroutine. */
+ static final int FLAG_SUBROUTINE_END = 64;
+
+ /**
+ * The number of elements to add to the {@link #otherLineNumbers} array when it needs to be
+ * resized to store a new source line number.
+ */
+ static final int LINE_NUMBERS_CAPACITY_INCREMENT = 4;
+
+ /**
+ * The number of elements to add to the {@link #forwardReferences} array when it needs to be
+ * resized to store a new forward reference.
+ */
+ static final int FORWARD_REFERENCES_CAPACITY_INCREMENT = 6;
+
+ /**
+ * The bit mask to extract the type of a forward reference to this label. The extracted type is
+ * either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link #FORWARD_REFERENCE_TYPE_WIDE}.
+ *
+ * @see #forwardReferences
+ */
+ static final int FORWARD_REFERENCE_TYPE_MASK = 0xF0000000;
+
+ /**
+ * The type of forward references stored with two bytes in the bytecode. This is the case, for
+ * instance, of a forward reference from an ifnull instruction.
+ */
+ static final int FORWARD_REFERENCE_TYPE_SHORT = 0x10000000;
+
+ /**
+ * The type of forward references stored in four bytes in the bytecode. This is the case, for
+ * instance, of a forward reference from a lookupswitch instruction.
+ */
+ static final int FORWARD_REFERENCE_TYPE_WIDE = 0x20000000;
+
+ /**
+ * The bit mask to extract the 'handle' of a forward reference to this label. The extracted handle
+ * is the bytecode offset where the forward reference value is stored (using either 2 or 4 bytes,
+ * as indicated by the {@link #FORWARD_REFERENCE_TYPE_MASK}).
+ *
+ * @see #forwardReferences
+ */
+ static final int FORWARD_REFERENCE_HANDLE_MASK = 0x0FFFFFFF;
+
+ /**
+ * A sentinel element used to indicate the end of a list of labels.
+ *
+ * @see #nextListElement
+ */
+ static final Label EMPTY_LIST = new Label();
+
+ /**
+ * A user managed state associated with this label. Warning: this field is used by the ASM tree
+ * package. In order to use it with the ASM tree package you must override the getLabelNode method
+ * in MethodNode.
+ */
+ public Object info;
+
+ /**
+ * The type and status of this label or its corresponding basic block. Must be zero or more of
+ * {@link #FLAG_DEBUG_ONLY}, {@link #FLAG_JUMP_TARGET}, {@link #FLAG_RESOLVED}, {@link
+ * #FLAG_REACHABLE}, {@link #FLAG_SUBROUTINE_CALLER}, {@link #FLAG_SUBROUTINE_START}, {@link
+ * #FLAG_SUBROUTINE_END}.
+ */
+ short flags;
+
+ /**
+ * The source line number corresponding to this label, or 0. If there are several source line
+ * numbers corresponding to this label, the first one is stored in this field, and the remaining
+ * ones are stored in {@link #otherLineNumbers}.
+ */
+ private short lineNumber;
+
+ /**
+ * The source line numbers corresponding to this label, in addition to {@link #lineNumber}, or
+ * null. The first element of this array is the number n of source line numbers it contains, which
+ * are stored between indices 1 and n (inclusive).
+ */
+ private int[] otherLineNumbers;
+
+ /**
+ * The offset of this label in the bytecode of its method, in bytes. This value is set if and only
+ * if the {@link #FLAG_RESOLVED} flag is set.
+ */
+ int bytecodeOffset;
+
+ /**
+ * The forward references to this label. The first element is the number of forward references,
+ * times 2 (this corresponds to the index of the last element actually used in this array). Then,
+ * each forward reference is described with two consecutive integers noted
+ * 'sourceInsnBytecodeOffset' and 'reference':
+ *
+ * <ul>
+ * <li>'sourceInsnBytecodeOffset' is the bytecode offset of the instruction that contains the
+ * forward reference,
+ * <li>'reference' contains the type and the offset in the bytecode where the forward reference
+ * value must be stored, which can be extracted with {@link #FORWARD_REFERENCE_TYPE_MASK}
+ * and {@link #FORWARD_REFERENCE_HANDLE_MASK}.
+ * </ul>
+ *
+ * <p>For instance, for an ifnull instruction at bytecode offset x, 'sourceInsnBytecodeOffset' is
+ * equal to x, and 'reference' is of type {@link #FORWARD_REFERENCE_TYPE_SHORT} with value x + 1
+ * (because the ifnull instruction uses a 2 bytes bytecode offset operand stored one byte after
+ * the start of the instruction itself). For the default case of a lookupswitch instruction at
+ * bytecode offset x, 'sourceInsnBytecodeOffset' is equal to x, and 'reference' is of type {@link
+ * #FORWARD_REFERENCE_TYPE_WIDE} with value between x + 1 and x + 4 (because the lookupswitch
+ * instruction uses a 4 bytes bytecode offset operand stored one to four bytes after the start of
+ * the instruction itself).
+ */
+ private int[] forwardReferences;
+
+ // -----------------------------------------------------------------------------------------------
+
+ // Fields for the control flow and data flow graph analysis algorithms (used to compute the
+ // maximum stack size or the stack map frames). A control flow graph contains one node per "basic
+ // block", and one edge per "jump" from one basic block to another. Each node (i.e., each basic
+ // block) is represented with the Label object that corresponds to the first instruction of this
+ // basic block. Each node also stores the list of its successors in the graph, as a linked list of
+ // Edge objects.
+ //
+ // The control flow analysis algorithms used to compute the maximum stack size or the stack map
+ // frames are similar and use two steps. The first step, during the visit of each instruction,
+ // builds information about the state of the local variables and the operand stack at the end of
+ // each basic block, called the "output frame", <i>relatively</i> to the frame state at the
+ // beginning of the basic block, which is called the "input frame", and which is <i>unknown</i>
+ // during this step. The second step, in {@link MethodWriter#computeAllFrames} and {@link
+ // MethodWriter#computeMaxStackAndLocal}, is a fix point algorithm
+ // that computes information about the input frame of each basic block, from the input state of
+ // the first basic block (known from the method signature), and by the using the previously
+ // computed relative output frames.
+ //
+ // The algorithm used to compute the maximum stack size only computes the relative output and
+ // absolute input stack heights, while the algorithm used to compute stack map frames computes
+ // relative output frames and absolute input frames.
+
+ /**
+ * The number of elements in the input stack of the basic block corresponding to this label. This
+ * field is computed in {@link MethodWriter#computeMaxStackAndLocal}.
+ */
+ short inputStackSize;
+
+ /**
+ * The number of elements in the output stack, at the end of the basic block corresponding to this
+ * label. This field is only computed for basic blocks that end with a RET instruction.
+ */
+ short outputStackSize;
+
+ /**
+ * The maximum height reached by the output stack, relatively to the top of the input stack, in
+ * the basic block corresponding to this label. This maximum is always positive or {@literal
+ * null}.
+ */
+ short outputStackMax;
+
+ /**
+ * The id of the subroutine to which this basic block belongs, or 0. If the basic block belongs to
+ * several subroutines, this is the id of the "oldest" subroutine that contains it (with the
+ * convention that a subroutine calling another one is "older" than the callee). This field is
+ * computed in {@link MethodWriter#computeMaxStackAndLocal}, if the method contains JSR
+ * instructions.
+ */
+ short subroutineId;
+
+ /**
+ * The input and output stack map frames of the basic block corresponding to this label. This
+ * field is only used when the {@link MethodWriter#COMPUTE_ALL_FRAMES} or {@link
+ * MethodWriter#COMPUTE_INSERTED_FRAMES} option is used.
+ */
+ Frame frame;
+
+ /**
+ * The successor of this label, in the order they are visited in {@link MethodVisitor#visitLabel}.
+ * This linked list does not include labels used for debug info only. If the {@link
+ * MethodWriter#COMPUTE_ALL_FRAMES} or {@link MethodWriter#COMPUTE_INSERTED_FRAMES} option is used
+ * then it does not contain either successive labels that denote the same bytecode offset (in this
+ * case only the first label appears in this list).
+ */
+ Label nextBasicBlock;
+
+ /**
+ * The outgoing edges of the basic block corresponding to this label, in the control flow graph of
+ * its method. These edges are stored in a linked list of {@link Edge} objects, linked to each
+ * other by their {@link Edge#nextEdge} field.
+ */
+ Edge outgoingEdges;
+
+ /**
+ * The next element in the list of labels to which this label belongs, or {@literal null} if it
+ * does not belong to any list. All lists of labels must end with the {@link #EMPTY_LIST}
+ * sentinel, in order to ensure that this field is null if and only if this label does not belong
+ * to a list of labels. Note that there can be several lists of labels at the same time, but that
+ * a label can belong to at most one list at a time (unless some lists share a common tail, but
+ * this is not used in practice).
+ *
+ * <p>List of labels are used in {@link MethodWriter#computeAllFrames} and {@link
+ * MethodWriter#computeMaxStackAndLocal} to compute stack map frames and the maximum stack size,
+ * respectively, as well as in {@link #markSubroutine} and {@link #addSubroutineRetSuccessors} to
+ * compute the basic blocks belonging to subroutines and their outgoing edges. Outside of these
+ * methods, this field should be null (this property is a precondition and a postcondition of
+ * these methods).
+ */
+ Label nextListElement;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor and accessors
+ // -----------------------------------------------------------------------------------------------
+
+ /** Constructs a new label. */
+ public Label() {
+ // Nothing to do.
+ }
+
+ /**
+ * Returns the bytecode offset corresponding to this label. This offset is computed from the start
+ * of the method's bytecode. <i>This method is intended for {@link Attribute} sub classes, and is
+ * normally not needed by class generators or adapters.</i>
+ *
+ * @return the bytecode offset corresponding to this label.
+ * @throws IllegalStateException if this label is not resolved yet.
+ */
+ public int getOffset() {
+ if ((flags & FLAG_RESOLVED) == 0) {
+ throw new IllegalStateException("Label offset position has not been resolved yet");
+ }
+ return bytecodeOffset;
+ }
+
+ /**
+ * Returns the "canonical" {@link Label} instance corresponding to this label's bytecode offset,
+ * if known, otherwise the label itself. The canonical instance is the first label (in the order
+ * of their visit by {@link MethodVisitor#visitLabel}) corresponding to this bytecode offset. It
+ * cannot be known for labels which have not been visited yet.
+ *
+ * <p><i>This method should only be used when the {@link MethodWriter#COMPUTE_ALL_FRAMES} option
+ * is used.</i>
+ *
+ * @return the label itself if {@link #frame} is null, otherwise the Label's frame owner. This
+ * corresponds to the "canonical" label instance described above thanks to the way the label
+ * frame is set in {@link MethodWriter#visitLabel}.
+ */
+ final Label getCanonicalInstance() {
+ return frame == null ? this : frame.owner;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to manage line numbers
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds a source line number corresponding to this label.
+ *
+ * @param lineNumber a source line number (which should be strictly positive).
+ */
+ final void addLineNumber(final int lineNumber) {
+ if (this.lineNumber == 0) {
+ this.lineNumber = (short) lineNumber;
+ } else {
+ if (otherLineNumbers == null) {
+ otherLineNumbers = new int[LINE_NUMBERS_CAPACITY_INCREMENT];
+ }
+ int otherLineNumberIndex = ++otherLineNumbers[0];
+ if (otherLineNumberIndex >= otherLineNumbers.length) {
+ int[] newLineNumbers = new int[otherLineNumbers.length + LINE_NUMBERS_CAPACITY_INCREMENT];
+ System.arraycopy(otherLineNumbers, 0, newLineNumbers, 0, otherLineNumbers.length);
+ otherLineNumbers = newLineNumbers;
+ }
+ otherLineNumbers[otherLineNumberIndex] = lineNumber;
+ }
+ }
+
+ /**
+ * Makes the given visitor visit this label and its source line numbers, if applicable.
+ *
+ * @param methodVisitor a method visitor.
+ * @param visitLineNumbers whether to visit of the label's source line numbers, if any.
+ */
+ final void accept(final MethodVisitor methodVisitor, final boolean visitLineNumbers) {
+ methodVisitor.visitLabel(this);
+ if (visitLineNumbers && lineNumber != 0) {
+ methodVisitor.visitLineNumber(lineNumber & 0xFFFF, this);
+ if (otherLineNumbers != null) {
+ for (int i = 1; i <= otherLineNumbers[0]; ++i) {
+ methodVisitor.visitLineNumber(otherLineNumbers[i], this);
+ }
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to compute offsets and to manage forward references
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Puts a reference to this label in the bytecode of a method. If the bytecode offset of the label
+ * is known, the relative bytecode offset between the label and the instruction referencing it is
+ * computed and written directly. Otherwise, a null relative offset is written and a new forward
+ * reference is declared for this label.
+ *
+ * @param code the bytecode of the method. This is where the reference is appended.
+ * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the
+ * reference to be appended.
+ * @param wideReference whether the reference must be stored in 4 bytes (instead of 2 bytes).
+ */
+ final void put(
+ final ByteVector code, final int sourceInsnBytecodeOffset, final boolean wideReference) {
+ if ((flags & FLAG_RESOLVED) == 0) {
+ if (wideReference) {
+ addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_WIDE, code.length);
+ code.putInt(-1);
+ } else {
+ addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_SHORT, code.length);
+ code.putShort(-1);
+ }
+ } else {
+ if (wideReference) {
+ code.putInt(bytecodeOffset - sourceInsnBytecodeOffset);
+ } else {
+ code.putShort(bytecodeOffset - sourceInsnBytecodeOffset);
+ }
+ }
+ }
+
+ /**
+ * Adds a forward reference to this label. This method must be called only for a true forward
+ * reference, i.e. only if this label is not resolved yet. For backward references, the relative
+ * bytecode offset of the reference can be, and must be, computed and stored directly.
+ *
+ * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the
+ * reference stored at referenceHandle.
+ * @param referenceType either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link
+ * #FORWARD_REFERENCE_TYPE_WIDE}.
+ * @param referenceHandle the offset in the bytecode where the forward reference value must be
+ * stored.
+ */
+ private void addForwardReference(
+ final int sourceInsnBytecodeOffset, final int referenceType, final int referenceHandle) {
+ if (forwardReferences == null) {
+ forwardReferences = new int[FORWARD_REFERENCES_CAPACITY_INCREMENT];
+ }
+ int lastElementIndex = forwardReferences[0];
+ if (lastElementIndex + 2 >= forwardReferences.length) {
+ int[] newValues = new int[forwardReferences.length + FORWARD_REFERENCES_CAPACITY_INCREMENT];
+ System.arraycopy(forwardReferences, 0, newValues, 0, forwardReferences.length);
+ forwardReferences = newValues;
+ }
+ forwardReferences[++lastElementIndex] = sourceInsnBytecodeOffset;
+ forwardReferences[++lastElementIndex] = referenceType | referenceHandle;
+ forwardReferences[0] = lastElementIndex;
+ }
+
+ /**
+ * Sets the bytecode offset of this label to the given value and resolves the forward references
+ * to this label, if any. This method must be called when this label is added to the bytecode of
+ * the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that
+ * where left in the bytecode by each forward reference previously added to this label.
+ *
+ * @param code the bytecode of the method.
+ * @param bytecodeOffset the bytecode offset of this label.
+ * @return {@literal true} if a blank that was left for this label was too small to store the
+ * offset. In such a case the corresponding jump instruction is replaced with an equivalent
+ * ASM specific instruction using an unsigned two bytes offset. These ASM specific
+ * instructions are later replaced with standard bytecode instructions with wider offsets (4
+ * bytes instead of 2), in ClassReader.
+ */
+ final boolean resolve(final byte[] code, final int bytecodeOffset) {
+ this.flags |= FLAG_RESOLVED;
+ this.bytecodeOffset = bytecodeOffset;
+ if (forwardReferences == null) {
+ return false;
+ }
+ boolean hasAsmInstructions = false;
+ for (int i = forwardReferences[0]; i > 0; i -= 2) {
+ final int sourceInsnBytecodeOffset = forwardReferences[i - 1];
+ final int reference = forwardReferences[i];
+ final int relativeOffset = bytecodeOffset - sourceInsnBytecodeOffset;
+ int handle = reference & FORWARD_REFERENCE_HANDLE_MASK;
+ if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_SHORT) {
+ if (relativeOffset < Short.MIN_VALUE || relativeOffset > Short.MAX_VALUE) {
+ // Change the opcode of the jump instruction, in order to be able to find it later in
+ // ClassReader. These ASM specific opcodes are similar to jump instruction opcodes, except
+ // that the 2 bytes offset is unsigned (and can therefore represent values from 0 to
+ // 65535, which is sufficient since the size of a method is limited to 65535 bytes).
+ int opcode = code[sourceInsnBytecodeOffset] & 0xFF;
+ if (opcode < Opcodes.IFNULL) {
+ // Change IFEQ ... JSR to ASM_IFEQ ... ASM_JSR.
+ code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_OPCODE_DELTA);
+ } else {
+ // Change IFNULL and IFNONNULL to ASM_IFNULL and ASM_IFNONNULL.
+ code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_IFNULL_OPCODE_DELTA);
+ }
+ hasAsmInstructions = true;
+ }
+ code[handle++] = (byte) (relativeOffset >>> 8);
+ code[handle] = (byte) relativeOffset;
+ } else {
+ code[handle++] = (byte) (relativeOffset >>> 24);
+ code[handle++] = (byte) (relativeOffset >>> 16);
+ code[handle++] = (byte) (relativeOffset >>> 8);
+ code[handle] = (byte) relativeOffset;
+ }
+ }
+ return hasAsmInstructions;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods related to subroutines
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Finds the basic blocks that belong to the subroutine starting with the basic block
+ * corresponding to this label, and marks these blocks as belonging to this subroutine. This
+ * method follows the control flow graph to find all the blocks that are reachable from the
+ * current basic block WITHOUT following any jsr target.
+ *
+ * <p>Note: a precondition and postcondition of this method is that all labels must have a null
+ * {@link #nextListElement}.
+ *
+ * @param subroutineId the id of the subroutine starting with the basic block corresponding to
+ * this label.
+ */
+ final void markSubroutine(final short subroutineId) {
+ // Data flow algorithm: put this basic block in a list of blocks to process (which are blocks
+ // belonging to subroutine subroutineId) and, while there are blocks to process, remove one from
+ // the list, mark it as belonging to the subroutine, and add its successor basic blocks in the
+ // control flow graph to the list of blocks to process (if not already done).
+ Label listOfBlocksToProcess = this;
+ listOfBlocksToProcess.nextListElement = EMPTY_LIST;
+ while (listOfBlocksToProcess != EMPTY_LIST) {
+ // Remove a basic block from the list of blocks to process.
+ Label basicBlock = listOfBlocksToProcess;
+ listOfBlocksToProcess = listOfBlocksToProcess.nextListElement;
+ basicBlock.nextListElement = null;
+
+ // If it is not already marked as belonging to a subroutine, mark it as belonging to
+ // subroutineId and add its successors to the list of blocks to process (unless already done).
+ if (basicBlock.subroutineId == 0) {
+ basicBlock.subroutineId = subroutineId;
+ listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess);
+ }
+ }
+ }
+
+ /**
+ * Finds the basic blocks that end a subroutine starting with the basic block corresponding to
+ * this label and, for each one of them, adds an outgoing edge to the basic block following the
+ * given subroutine call. In other words, completes the control flow graph by adding the edges
+ * corresponding to the return from this subroutine, when called from the given caller basic
+ * block.
+ *
+ * <p>Note: a precondition and postcondition of this method is that all labels must have a null
+ * {@link #nextListElement}.
+ *
+ * @param subroutineCaller a basic block that ends with a jsr to the basic block corresponding to
+ * this label. This label is supposed to correspond to the start of a subroutine.
+ */
+ final void addSubroutineRetSuccessors(final Label subroutineCaller) {
+ // Data flow algorithm: put this basic block in a list blocks to process (which are blocks
+ // belonging to a subroutine starting with this label) and, while there are blocks to process,
+ // remove one from the list, put it in a list of blocks that have been processed, add a return
+ // edge to the successor of subroutineCaller if applicable, and add its successor basic blocks
+ // in the control flow graph to the list of blocks to process (if not already done).
+ Label listOfProcessedBlocks = EMPTY_LIST;
+ Label listOfBlocksToProcess = this;
+ listOfBlocksToProcess.nextListElement = EMPTY_LIST;
+ while (listOfBlocksToProcess != EMPTY_LIST) {
+ // Move a basic block from the list of blocks to process to the list of processed blocks.
+ Label basicBlock = listOfBlocksToProcess;
+ listOfBlocksToProcess = basicBlock.nextListElement;
+ basicBlock.nextListElement = listOfProcessedBlocks;
+ listOfProcessedBlocks = basicBlock;
+
+ // Add an edge from this block to the successor of the caller basic block, if this block is
+ // the end of a subroutine and if this block and subroutineCaller do not belong to the same
+ // subroutine.
+ if ((basicBlock.flags & FLAG_SUBROUTINE_END) != 0
+ && basicBlock.subroutineId != subroutineCaller.subroutineId) {
+ basicBlock.outgoingEdges =
+ new Edge(
+ basicBlock.outputStackSize,
+ // By construction, the first outgoing edge of a basic block that ends with a jsr
+ // instruction leads to the jsr continuation block, i.e. where execution continues
+ // when ret is called (see {@link #FLAG_SUBROUTINE_CALLER}).
+ subroutineCaller.outgoingEdges.successor,
+ basicBlock.outgoingEdges);
+ }
+ // Add its successors to the list of blocks to process. Note that {@link #pushSuccessors} does
+ // not push basic blocks which are already in a list. Here this means either in the list of
+ // blocks to process, or in the list of already processed blocks. This second list is
+ // important to make sure we don't reprocess an already processed block.
+ listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess);
+ }
+ // Reset the {@link #nextListElement} of all the basic blocks that have been processed to null,
+ // so that this method can be called again with a different subroutine or subroutine caller.
+ while (listOfProcessedBlocks != EMPTY_LIST) {
+ Label newListOfProcessedBlocks = listOfProcessedBlocks.nextListElement;
+ listOfProcessedBlocks.nextListElement = null;
+ listOfProcessedBlocks = newListOfProcessedBlocks;
+ }
+ }
+
+ /**
+ * Adds the successors of this label in the method's control flow graph (except those
+ * corresponding to a jsr target, and those already in a list of labels) to the given list of
+ * blocks to process, and returns the new list.
+ *
+ * @param listOfLabelsToProcess a list of basic blocks to process, linked together with their
+ * {@link #nextListElement} field.
+ * @return the new list of blocks to process.
+ */
+ private Label pushSuccessors(final Label listOfLabelsToProcess) {
+ Label newListOfLabelsToProcess = listOfLabelsToProcess;
+ Edge outgoingEdge = outgoingEdges;
+ while (outgoingEdge != null) {
+ // By construction, the second outgoing edge of a basic block that ends with a jsr instruction
+ // leads to the jsr target (see {@link #FLAG_SUBROUTINE_CALLER}).
+ boolean isJsrTarget =
+ (flags & Label.FLAG_SUBROUTINE_CALLER) != 0 && outgoingEdge == outgoingEdges.nextEdge;
+ if (!isJsrTarget && outgoingEdge.successor.nextListElement == null) {
+ // Add this successor to the list of blocks to process, if it does not already belong to a
+ // list of labels.
+ outgoingEdge.successor.nextListElement = newListOfLabelsToProcess;
+ newListOfLabelsToProcess = outgoingEdge.successor;
+ }
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ return newListOfLabelsToProcess;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Overridden Object methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns a string representation of this label.
+ *
+ * @return a string representation of this label.
+ */
+ @Override
+ public String toString() {
+ return "L" + System.identityHashCode(this);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/MethodTooLargeException.java b/asm/src/main/java/org/objectweb/asm/MethodTooLargeException.java
new file mode 100644
index 00000000..2fbf23b0
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/MethodTooLargeException.java
@@ -0,0 +1,99 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * Exception thrown when the Code attribute of a method produced by a {@link ClassWriter} is too
+ * large.
+ *
+ * @author Jason Zaugg
+ */
+public final class MethodTooLargeException extends IndexOutOfBoundsException {
+ private static final long serialVersionUID = 6807380416709738314L;
+
+ private final String className;
+ private final String methodName;
+ private final String descriptor;
+ private final int codeSize;
+
+ /**
+ * Constructs a new {@link MethodTooLargeException}.
+ *
+ * @param className the internal name of the owner class (see {@link Type#getInternalName()}).
+ * @param methodName the name of the method.
+ * @param descriptor the descriptor of the method.
+ * @param codeSize the size of the method's Code attribute, in bytes.
+ */
+ public MethodTooLargeException(
+ final String className,
+ final String methodName,
+ final String descriptor,
+ final int codeSize) {
+ super("Method too large: " + className + "." + methodName + " " + descriptor);
+ this.className = className;
+ this.methodName = methodName;
+ this.descriptor = descriptor;
+ this.codeSize = codeSize;
+ }
+
+ /**
+ * Returns the internal name of the owner class.
+ *
+ * @return the internal name of the owner class (see {@link Type#getInternalName()}).
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Returns the name of the method.
+ *
+ * @return the name of the method.
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * Returns the descriptor of the method.
+ *
+ * @return the descriptor of the method.
+ */
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the size of the method's Code attribute, in bytes.
+ *
+ * @return the size of the method's Code attribute, in bytes.
+ */
+ public int getCodeSize() {
+ return codeSize;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/MethodVisitor.java b/asm/src/main/java/org/objectweb/asm/MethodVisitor.java
new file mode 100644
index 00000000..529f4667
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/MethodVisitor.java
@@ -0,0 +1,799 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java method. The methods of this class must be called in the following
+ * order: ( {@code visitParameter} )* [ {@code visitAnnotationDefault} ] ( {@code visitAnnotation} |
+ * {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} | {@code
+ * visitTypeAnnotation} | {@code visitAttribute} )* [ {@code visitCode} ( {@code visitFrame} |
+ * {@code visit<i>X</i>Insn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code
+ * visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code
+ * visitLocalVariableAnnotation} | {@code visitLineNumber} )* {@code visitMaxs} ] {@code visitEnd}.
+ * In addition, the {@code visit<i>X</i>Insn} and {@code visitLabel} methods must be called in the
+ * sequential order of the bytecode instructions of the visited code, {@code visitInsnAnnotation}
+ * must be called <i>after</i> the annotated instruction, {@code visitTryCatchBlock} must be called
+ * <i>before</i> the labels passed as arguments have been visited, {@code
+ * visitTryCatchBlockAnnotation} must be called <i>after</i> the corresponding try catch block has
+ * been visited, and the {@code visitLocalVariable}, {@code visitLocalVariableAnnotation} and {@code
+ * visitLineNumber} methods must be called <i>after</i> the labels passed as arguments have been
+ * visited.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class MethodVisitor {
+
+ private static final String REQUIRES_ASM5 = "This feature requires ASM5";
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /**
+ * The method visitor to which this visitor must delegate method calls. May be {@literal null}.
+ */
+ protected MethodVisitor mv;
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected MethodVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link MethodVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ * @param methodVisitor the method visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected MethodVisitor(final int api, final MethodVisitor methodVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.mv = methodVisitor;
+ }
+
+ /**
+ * The method visitor to which this visitor must delegate method calls. May be {@literal null}.
+ *
+ * @return the method visitor to which this visitor must delegate method calls, or {@literal
+ * null}.
+ */
+ public MethodVisitor getDelegate() {
+ return mv;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Parameters, annotations and non standard attributes
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits a parameter of this method.
+ *
+ * @param name parameter name or {@literal null} if none is provided.
+ * @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC}
+ * or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}).
+ */
+ public void visitParameter(final String name, final int access) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ mv.visitParameter(name, access);
+ }
+ }
+
+ /**
+ * Visits the default value of this annotation interface method.
+ *
+ * @return a visitor to the visit the actual default value of this annotation interface method, or
+ * {@literal null} if this visitor is not interested in visiting this default value. The
+ * 'name' parameters passed to the methods of this annotation visitor are ignored. Moreover,
+ * exactly one visit method must be called on this annotation visitor, followed by visitEnd.
+ */
+ public AnnotationVisitor visitAnnotationDefault() {
+ if (mv != null) {
+ return mv.visitAnnotationDefault();
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation of this method.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (mv != null) {
+ return mv.visitAnnotation(descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on a type in the method signature.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#METHOD_TYPE_PARAMETER}, {@link
+ * TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link TypeReference#METHOD_RETURN}, {@link
+ * TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link
+ * TypeReference#THROWS}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ return mv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits the number of method parameters that can have annotations. By default (i.e. when this
+ * method is not called), all the method parameters defined by the method descriptor can have
+ * annotations.
+ *
+ * @param parameterCount the number of method parameters than can have annotations. This number
+ * must be less or equal than the number of parameter types in the method descriptor. It can
+ * be strictly less when a method has synthetic parameters and when these parameters are
+ * ignored when computing parameter indices for the purpose of parameter annotations (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ * @param visible {@literal true} to define the number of method parameters that can have
+ * annotations visible at runtime, {@literal false} to define the number of method parameters
+ * that can have annotations invisible at runtime.
+ */
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ if (mv != null) {
+ mv.visitAnnotableParameterCount(parameterCount, visible);
+ }
+ }
+
+ /**
+ * Visits an annotation of a parameter this method.
+ *
+ * @param parameter the parameter index. This index must be strictly smaller than the number of
+ * parameters in the method descriptor, and strictly smaller than the parameter count
+ * specified in {@link #visitAnnotableParameterCount}. Important note: <i>a parameter index i
+ * is not required to correspond to the i'th parameter descriptor in the method
+ * descriptor</i>, in particular in case of synthetic parameters (see
+ * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ if (mv != null) {
+ return mv.visitParameterAnnotation(parameter, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a non standard attribute of this method.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ if (mv != null) {
+ mv.visitAttribute(attribute);
+ }
+ }
+
+ /** Starts the visit of the method's code, if any (i.e. non abstract method). */
+ public void visitCode() {
+ if (mv != null) {
+ mv.visitCode();
+ }
+ }
+
+ /**
+ * Visits the current state of the local variables and operand stack elements. This method must(*)
+ * be called <i>just before</i> any instruction <b>i</b> that follows an unconditional branch
+ * instruction such as GOTO or THROW, that is the target of a jump instruction, or that starts an
+ * exception handler block. The visited types must describe the values of the local variables and
+ * of the operand stack elements <i>just before</i> <b>i</b> is executed.<br>
+ * <br>
+ * (*) this is mandatory only for classes whose version is greater than or equal to {@link
+ * Opcodes#V1_6}. <br>
+ * <br>
+ * The frames of a method must be given either in expanded form, or in compressed form (all frames
+ * must use the same format, i.e. you must not mix expanded and compressed frames within a single
+ * method):
+ *
+ * <ul>
+ * <li>In expanded form, all frames must have the F_NEW type.
+ * <li>In compressed form, frames are basically "deltas" from the state of the previous frame:
+ * <ul>
+ * <li>{@link Opcodes#F_SAME} representing frame with exactly the same locals as the
+ * previous frame and with the empty stack.
+ * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same locals as the
+ * previous frame and with single value on the stack ( <code>numStack</code> is 1 and
+ * <code>stack[0]</code> contains value for the type of the stack item).
+ * <li>{@link Opcodes#F_APPEND} representing frame with current locals are the same as the
+ * locals in the previous frame, except that additional locals are defined (<code>
+ * numLocal</code> is 1, 2 or 3 and <code>local</code> elements contains values
+ * representing added types).
+ * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the same as the
+ * locals in the previous frame, except that the last 1-3 locals are absent and with
+ * the empty stack (<code>numLocal</code> is 1, 2 or 3).
+ * <li>{@link Opcodes#F_FULL} representing complete frame data.
+ * </ul>
+ * </ul>
+ *
+ * <br>
+ * In both cases the first frame, corresponding to the method's parameters and access flags, is
+ * implicit and must not be visited. Also, it is illegal to visit two or more frames for the same
+ * code location (i.e., at least one instruction must be visited between two calls to visitFrame).
+ *
+ * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded
+ * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link
+ * Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
+ * @param numLocal the number of local variables in the visited frame. Long and double values
+ * count for one variable.
+ * @param local the local variable types in this frame. This array must not be modified. Primitive
+ * types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
+ * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element).
+ * Reference types are represented by String objects (representing internal names, see {@link
+ * Type#getInternalName()}), and uninitialized types by Label objects (this label designates
+ * the NEW instruction that created this uninitialized value).
+ * @param numStack the number of operand stack elements in the visited frame. Long and double
+ * values count for one stack element.
+ * @param stack the operand stack types in this frame. This array must not be modified. Its
+ * content has the same format as the "local" array.
+ * @throws IllegalStateException if a frame is visited just after another one, without any
+ * instruction between the two (unless this frame is a Opcodes#F_SAME frame, in which case it
+ * is silently ignored).
+ */
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ if (mv != null) {
+ mv.visitFrame(type, numLocal, local, numStack, stack);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Normal instructions
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits a zero operand instruction.
+ *
+ * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
+ * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
+ * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
+ * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
+ * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
+ * SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
+ * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
+ * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
+ * D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
+ */
+ public void visitInsn(final int opcode) {
+ if (mv != null) {
+ mv.visitInsn(opcode);
+ }
+ }
+
+ /**
+ * Visits an instruction with a single int operand.
+ *
+ * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH
+ * or NEWARRAY.
+ * @param operand the operand of the instruction to be visited.<br>
+ * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.
+ * <br>
+ * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.
+ * <br>
+ * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link
+ * Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE},
+ * {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+ */
+ public void visitIntInsn(final int opcode, final int operand) {
+ if (mv != null) {
+ mv.visitIntInsn(opcode, operand);
+ }
+ }
+
+ /**
+ * Visits a local variable instruction. A local variable instruction is an instruction that loads
+ * or stores the value of a local variable.
+ *
+ * @param opcode the opcode of the local variable instruction to be visited. This opcode is either
+ * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param varIndex the operand of the instruction to be visited. This operand is the index of a
+ * local variable.
+ */
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ if (mv != null) {
+ mv.visitVarInsn(opcode, varIndex);
+ }
+ }
+
+ /**
+ * Visits a type instruction. A type instruction is an instruction that takes the internal name of
+ * a class as parameter (see {@link Type#getInternalName()}).
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
+ * ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param type the operand of the instruction to be visited. This operand must be the internal
+ * name of an object or array class (see {@link Type#getInternalName()}).
+ */
+ public void visitTypeInsn(final int opcode, final String type) {
+ if (mv != null) {
+ mv.visitTypeInsn(opcode, type);
+ }
+ }
+
+ /**
+ * Visits a field instruction. A field instruction is an instruction that loads or stores the
+ * value of a field of an object.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}).
+ * @param name the field's name.
+ * @param descriptor the field's descriptor (see {@link Type}).
+ */
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ if (mv != null) {
+ mv.visitFieldInsn(opcode, owner, name, descriptor);
+ }
+ }
+
+ /**
+ * Visits a method instruction. A method instruction is an instruction that invokes a method.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
+ */
+ @Deprecated
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ int opcodeAndSource = opcode | (api < Opcodes.ASM5 ? Opcodes.SOURCE_DEPRECATED : 0);
+ visitMethodInsn(opcodeAndSource, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
+ }
+
+ /**
+ * Visits a method instruction. A method instruction is an instruction that invokes a method.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either
+ * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param owner the internal name of the method's owner class (see {@link
+ * Type#getInternalName()}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param isInterface if the method's owner class is an interface.
+ */
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcode & Opcodes.SOURCE_DEPRECATED) == 0) {
+ if (isInterface != (opcode == Opcodes.INVOKEINTERFACE)) {
+ throw new UnsupportedOperationException("INVOKESPECIAL/STATIC on interfaces requires ASM5");
+ }
+ visitMethodInsn(opcode, owner, name, descriptor);
+ return;
+ }
+ if (mv != null) {
+ mv.visitMethodInsn(opcode & ~Opcodes.SOURCE_MASK, owner, name, descriptor, isInterface);
+ }
+ }
+
+ /**
+ * Visits an invokedynamic instruction.
+ *
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param bootstrapMethodHandle the bootstrap method.
+ * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
+ * Type}, {@link Handle} or {@link ConstantDynamic} value. This method is allowed to modify
+ * the content of the array so a caller should expect that this array may change.
+ */
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ mv.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ }
+ }
+
+ /**
+ * Visits a jump instruction. A jump instruction is an instruction that may jump to another
+ * instruction.
+ *
+ * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
+ * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
+ * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label the operand of the instruction to be visited. This operand is a label that
+ * designates the instruction to which the jump instruction may jump.
+ */
+ public void visitJumpInsn(final int opcode, final Label label) {
+ if (mv != null) {
+ mv.visitJumpInsn(opcode, label);
+ }
+ }
+
+ /**
+ * Visits a label. A label designates the instruction that will be visited just after it.
+ *
+ * @param label a {@link Label} object.
+ */
+ public void visitLabel(final Label label) {
+ if (mv != null) {
+ mv.visitLabel(label);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Special instructions
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits a LDC instruction. Note that new constant types may be added in future versions of the
+ * Java Virtual Machine. To easily detect new constant types, implementations of this method
+ * should check for unexpected constant types, like this:
+ *
+ * <pre>
+ * if (cst instanceof Integer) {
+ * // ...
+ * } else if (cst instanceof Float) {
+ * // ...
+ * } else if (cst instanceof Long) {
+ * // ...
+ * } else if (cst instanceof Double) {
+ * // ...
+ * } else if (cst instanceof String) {
+ * // ...
+ * } else if (cst instanceof Type) {
+ * int sort = ((Type) cst).getSort();
+ * if (sort == Type.OBJECT) {
+ * // ...
+ * } else if (sort == Type.ARRAY) {
+ * // ...
+ * } else if (sort == Type.METHOD) {
+ * // ...
+ * } else {
+ * // throw an exception
+ * }
+ * } else if (cst instanceof Handle) {
+ * // ...
+ * } else if (cst instanceof ConstantDynamic) {
+ * // ...
+ * } else {
+ * // throw an exception
+ * }
+ * </pre>
+ *
+ * @param value the constant to be loaded on the stack. This parameter must be a non null {@link
+ * Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
+ * Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
+ * 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
+ * constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
+ * dynamic for classes whose version is 55.
+ */
+ public void visitLdcInsn(final Object value) {
+ if (api < Opcodes.ASM5
+ && (value instanceof Handle
+ || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (api < Opcodes.ASM7 && value instanceof ConstantDynamic) {
+ throw new UnsupportedOperationException("This feature requires ASM7");
+ }
+ if (mv != null) {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Visits an IINC instruction.
+ *
+ * @param varIndex index of the local variable to be incremented.
+ * @param increment amount to increment the local variable by.
+ */
+ public void visitIincInsn(final int varIndex, final int increment) {
+ if (mv != null) {
+ mv.visitIincInsn(varIndex, increment);
+ }
+ }
+
+ /**
+ * Visits a TABLESWITCH instruction.
+ *
+ * @param min the minimum key value.
+ * @param max the maximum key value.
+ * @param dflt beginning of the default handler block.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code min + i} key.
+ */
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ if (mv != null) {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+ }
+ }
+
+ /**
+ * Visits a LOOKUPSWITCH instruction.
+ *
+ * @param dflt beginning of the default handler block.
+ * @param keys the values of the keys.
+ * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
+ * handler block for the {@code keys[i]} key.
+ */
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ if (mv != null) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+ }
+ }
+
+ /**
+ * Visits a MULTIANEWARRAY instruction.
+ *
+ * @param descriptor an array type descriptor (see {@link Type}).
+ * @param numDimensions the number of dimensions of the array to allocate.
+ */
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ if (mv != null) {
+ mv.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+ }
+
+ /**
+ * Visits an annotation on an instruction. This method must be called just <i>after</i> the
+ * annotated instruction. It can be called several times for the same instruction.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#INSTANCEOF}, {@link TypeReference#NEW}, {@link
+ * TypeReference#CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE}, {@link
+ * TypeReference#CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
+ * TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
+ * TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ return mv.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Exceptions table entries, debug information, max stack and max locals
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Visits a try catch block.
+ *
+ * @param start the beginning of the exception handler's scope (inclusive).
+ * @param end the end of the exception handler's scope (exclusive).
+ * @param handler the beginning of the exception handler's code.
+ * @param type the internal name of the type of exceptions handled by the handler (see {@link
+ * Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally"
+ * blocks).
+ * @throws IllegalArgumentException if one of the labels has already been visited by this visitor
+ * (by the {@link #visitLabel} method).
+ */
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ if (mv != null) {
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+ }
+
+ /**
+ * Visits an annotation on an exception handler type. This method must be called <i>after</i> the
+ * {@link #visitTryCatchBlock} for the annotated exception handler. It can be called several times
+ * for the same exception handler.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ return mv.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a local variable declaration.
+ *
+ * @param name the name of a local variable.
+ * @param descriptor the type descriptor of this local variable.
+ * @param signature the type signature of this local variable. May be {@literal null} if the local
+ * variable type does not use generic types.
+ * @param start the first instruction corresponding to the scope of this local variable
+ * (inclusive).
+ * @param end the last instruction corresponding to the scope of this local variable (exclusive).
+ * @param index the local variable's index.
+ * @throws IllegalArgumentException if one of the labels has not already been visited by this
+ * visitor (by the {@link #visitLabel} method).
+ */
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ if (mv != null) {
+ mv.visitLocalVariable(name, descriptor, signature, start, end, index);
+ }
+ }
+
+ /**
+ * Visits an annotation on a local variable type.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link
+ * TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param start the fist instructions corresponding to the continuous ranges that make the scope
+ * of this local variable (inclusive).
+ * @param end the last instructions corresponding to the continuous ranges that make the scope of
+ * this local variable (exclusive). This array must have the same size as the 'start' array.
+ * @param index the local variable's index in each range. This array must have the same size as
+ * the 'start' array.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ if (api < Opcodes.ASM5) {
+ throw new UnsupportedOperationException(REQUIRES_ASM5);
+ }
+ if (mv != null) {
+ return mv.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a line number declaration.
+ *
+ * @param line a line number. This number refers to the source file from which the class was
+ * compiled.
+ * @param start the first instruction corresponding to this line number.
+ * @throws IllegalArgumentException if {@code start} has not already been visited by this visitor
+ * (by the {@link #visitLabel} method).
+ */
+ public void visitLineNumber(final int line, final Label start) {
+ if (mv != null) {
+ mv.visitLineNumber(line, start);
+ }
+ }
+
+ /**
+ * Visits the maximum stack size and the maximum number of local variables of the method.
+ *
+ * @param maxStack maximum stack size of the method.
+ * @param maxLocals maximum number of local variables for the method.
+ */
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ if (mv != null) {
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+ }
+
+ /**
+ * Visits the end of the method. This method, which is the last one to be called, is used to
+ * inform the visitor that all the annotations and attributes of the method have been visited.
+ */
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/MethodWriter.java b/asm/src/main/java/org/objectweb/asm/MethodWriter.java
new file mode 100644
index 00000000..d238d391
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/MethodWriter.java
@@ -0,0 +1,2394 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A {@link MethodVisitor} that generates a corresponding 'method_info' structure, as defined in the
+ * Java Virtual Machine Specification (JVMS).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6">JVMS
+ * 4.6</a>
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+final class MethodWriter extends MethodVisitor {
+
+ /** Indicates that nothing must be computed. */
+ static final int COMPUTE_NOTHING = 0;
+
+ /**
+ * Indicates that the maximum stack size and the maximum number of local variables must be
+ * computed, from scratch.
+ */
+ static final int COMPUTE_MAX_STACK_AND_LOCAL = 1;
+
+ /**
+ * Indicates that the maximum stack size and the maximum number of local variables must be
+ * computed, from the existing stack map frames. This can be done more efficiently than with the
+ * control flow graph algorithm used for {@link #COMPUTE_MAX_STACK_AND_LOCAL}, by using a linear
+ * scan of the bytecode instructions.
+ */
+ static final int COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES = 2;
+
+ /**
+ * Indicates that the stack map frames of type F_INSERT must be computed. The other frames are not
+ * computed. They should all be of type F_NEW and should be sufficient to compute the content of
+ * the F_INSERT frames, together with the bytecode instructions between a F_NEW and a F_INSERT
+ * frame - and without any knowledge of the type hierarchy (by definition of F_INSERT).
+ */
+ static final int COMPUTE_INSERTED_FRAMES = 3;
+
+ /**
+ * Indicates that all the stack map frames must be computed. In this case the maximum stack size
+ * and the maximum number of local variables is also computed.
+ */
+ static final int COMPUTE_ALL_FRAMES = 4;
+
+ /** Indicates that {@link #STACK_SIZE_DELTA} is not applicable (not constant or never used). */
+ private static final int NA = 0;
+
+ /**
+ * The stack size variation corresponding to each JVM opcode. The stack size variation for opcode
+ * 'o' is given by the array element at index 'o'.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html">JVMS 6</a>
+ */
+ private static final int[] STACK_SIZE_DELTA = {
+ 0, // nop = 0 (0x0)
+ 1, // aconst_null = 1 (0x1)
+ 1, // iconst_m1 = 2 (0x2)
+ 1, // iconst_0 = 3 (0x3)
+ 1, // iconst_1 = 4 (0x4)
+ 1, // iconst_2 = 5 (0x5)
+ 1, // iconst_3 = 6 (0x6)
+ 1, // iconst_4 = 7 (0x7)
+ 1, // iconst_5 = 8 (0x8)
+ 2, // lconst_0 = 9 (0x9)
+ 2, // lconst_1 = 10 (0xa)
+ 1, // fconst_0 = 11 (0xb)
+ 1, // fconst_1 = 12 (0xc)
+ 1, // fconst_2 = 13 (0xd)
+ 2, // dconst_0 = 14 (0xe)
+ 2, // dconst_1 = 15 (0xf)
+ 1, // bipush = 16 (0x10)
+ 1, // sipush = 17 (0x11)
+ 1, // ldc = 18 (0x12)
+ NA, // ldc_w = 19 (0x13)
+ NA, // ldc2_w = 20 (0x14)
+ 1, // iload = 21 (0x15)
+ 2, // lload = 22 (0x16)
+ 1, // fload = 23 (0x17)
+ 2, // dload = 24 (0x18)
+ 1, // aload = 25 (0x19)
+ NA, // iload_0 = 26 (0x1a)
+ NA, // iload_1 = 27 (0x1b)
+ NA, // iload_2 = 28 (0x1c)
+ NA, // iload_3 = 29 (0x1d)
+ NA, // lload_0 = 30 (0x1e)
+ NA, // lload_1 = 31 (0x1f)
+ NA, // lload_2 = 32 (0x20)
+ NA, // lload_3 = 33 (0x21)
+ NA, // fload_0 = 34 (0x22)
+ NA, // fload_1 = 35 (0x23)
+ NA, // fload_2 = 36 (0x24)
+ NA, // fload_3 = 37 (0x25)
+ NA, // dload_0 = 38 (0x26)
+ NA, // dload_1 = 39 (0x27)
+ NA, // dload_2 = 40 (0x28)
+ NA, // dload_3 = 41 (0x29)
+ NA, // aload_0 = 42 (0x2a)
+ NA, // aload_1 = 43 (0x2b)
+ NA, // aload_2 = 44 (0x2c)
+ NA, // aload_3 = 45 (0x2d)
+ -1, // iaload = 46 (0x2e)
+ 0, // laload = 47 (0x2f)
+ -1, // faload = 48 (0x30)
+ 0, // daload = 49 (0x31)
+ -1, // aaload = 50 (0x32)
+ -1, // baload = 51 (0x33)
+ -1, // caload = 52 (0x34)
+ -1, // saload = 53 (0x35)
+ -1, // istore = 54 (0x36)
+ -2, // lstore = 55 (0x37)
+ -1, // fstore = 56 (0x38)
+ -2, // dstore = 57 (0x39)
+ -1, // astore = 58 (0x3a)
+ NA, // istore_0 = 59 (0x3b)
+ NA, // istore_1 = 60 (0x3c)
+ NA, // istore_2 = 61 (0x3d)
+ NA, // istore_3 = 62 (0x3e)
+ NA, // lstore_0 = 63 (0x3f)
+ NA, // lstore_1 = 64 (0x40)
+ NA, // lstore_2 = 65 (0x41)
+ NA, // lstore_3 = 66 (0x42)
+ NA, // fstore_0 = 67 (0x43)
+ NA, // fstore_1 = 68 (0x44)
+ NA, // fstore_2 = 69 (0x45)
+ NA, // fstore_3 = 70 (0x46)
+ NA, // dstore_0 = 71 (0x47)
+ NA, // dstore_1 = 72 (0x48)
+ NA, // dstore_2 = 73 (0x49)
+ NA, // dstore_3 = 74 (0x4a)
+ NA, // astore_0 = 75 (0x4b)
+ NA, // astore_1 = 76 (0x4c)
+ NA, // astore_2 = 77 (0x4d)
+ NA, // astore_3 = 78 (0x4e)
+ -3, // iastore = 79 (0x4f)
+ -4, // lastore = 80 (0x50)
+ -3, // fastore = 81 (0x51)
+ -4, // dastore = 82 (0x52)
+ -3, // aastore = 83 (0x53)
+ -3, // bastore = 84 (0x54)
+ -3, // castore = 85 (0x55)
+ -3, // sastore = 86 (0x56)
+ -1, // pop = 87 (0x57)
+ -2, // pop2 = 88 (0x58)
+ 1, // dup = 89 (0x59)
+ 1, // dup_x1 = 90 (0x5a)
+ 1, // dup_x2 = 91 (0x5b)
+ 2, // dup2 = 92 (0x5c)
+ 2, // dup2_x1 = 93 (0x5d)
+ 2, // dup2_x2 = 94 (0x5e)
+ 0, // swap = 95 (0x5f)
+ -1, // iadd = 96 (0x60)
+ -2, // ladd = 97 (0x61)
+ -1, // fadd = 98 (0x62)
+ -2, // dadd = 99 (0x63)
+ -1, // isub = 100 (0x64)
+ -2, // lsub = 101 (0x65)
+ -1, // fsub = 102 (0x66)
+ -2, // dsub = 103 (0x67)
+ -1, // imul = 104 (0x68)
+ -2, // lmul = 105 (0x69)
+ -1, // fmul = 106 (0x6a)
+ -2, // dmul = 107 (0x6b)
+ -1, // idiv = 108 (0x6c)
+ -2, // ldiv = 109 (0x6d)
+ -1, // fdiv = 110 (0x6e)
+ -2, // ddiv = 111 (0x6f)
+ -1, // irem = 112 (0x70)
+ -2, // lrem = 113 (0x71)
+ -1, // frem = 114 (0x72)
+ -2, // drem = 115 (0x73)
+ 0, // ineg = 116 (0x74)
+ 0, // lneg = 117 (0x75)
+ 0, // fneg = 118 (0x76)
+ 0, // dneg = 119 (0x77)
+ -1, // ishl = 120 (0x78)
+ -1, // lshl = 121 (0x79)
+ -1, // ishr = 122 (0x7a)
+ -1, // lshr = 123 (0x7b)
+ -1, // iushr = 124 (0x7c)
+ -1, // lushr = 125 (0x7d)
+ -1, // iand = 126 (0x7e)
+ -2, // land = 127 (0x7f)
+ -1, // ior = 128 (0x80)
+ -2, // lor = 129 (0x81)
+ -1, // ixor = 130 (0x82)
+ -2, // lxor = 131 (0x83)
+ 0, // iinc = 132 (0x84)
+ 1, // i2l = 133 (0x85)
+ 0, // i2f = 134 (0x86)
+ 1, // i2d = 135 (0x87)
+ -1, // l2i = 136 (0x88)
+ -1, // l2f = 137 (0x89)
+ 0, // l2d = 138 (0x8a)
+ 0, // f2i = 139 (0x8b)
+ 1, // f2l = 140 (0x8c)
+ 1, // f2d = 141 (0x8d)
+ -1, // d2i = 142 (0x8e)
+ 0, // d2l = 143 (0x8f)
+ -1, // d2f = 144 (0x90)
+ 0, // i2b = 145 (0x91)
+ 0, // i2c = 146 (0x92)
+ 0, // i2s = 147 (0x93)
+ -3, // lcmp = 148 (0x94)
+ -1, // fcmpl = 149 (0x95)
+ -1, // fcmpg = 150 (0x96)
+ -3, // dcmpl = 151 (0x97)
+ -3, // dcmpg = 152 (0x98)
+ -1, // ifeq = 153 (0x99)
+ -1, // ifne = 154 (0x9a)
+ -1, // iflt = 155 (0x9b)
+ -1, // ifge = 156 (0x9c)
+ -1, // ifgt = 157 (0x9d)
+ -1, // ifle = 158 (0x9e)
+ -2, // if_icmpeq = 159 (0x9f)
+ -2, // if_icmpne = 160 (0xa0)
+ -2, // if_icmplt = 161 (0xa1)
+ -2, // if_icmpge = 162 (0xa2)
+ -2, // if_icmpgt = 163 (0xa3)
+ -2, // if_icmple = 164 (0xa4)
+ -2, // if_acmpeq = 165 (0xa5)
+ -2, // if_acmpne = 166 (0xa6)
+ 0, // goto = 167 (0xa7)
+ 1, // jsr = 168 (0xa8)
+ 0, // ret = 169 (0xa9)
+ -1, // tableswitch = 170 (0xaa)
+ -1, // lookupswitch = 171 (0xab)
+ -1, // ireturn = 172 (0xac)
+ -2, // lreturn = 173 (0xad)
+ -1, // freturn = 174 (0xae)
+ -2, // dreturn = 175 (0xaf)
+ -1, // areturn = 176 (0xb0)
+ 0, // return = 177 (0xb1)
+ NA, // getstatic = 178 (0xb2)
+ NA, // putstatic = 179 (0xb3)
+ NA, // getfield = 180 (0xb4)
+ NA, // putfield = 181 (0xb5)
+ NA, // invokevirtual = 182 (0xb6)
+ NA, // invokespecial = 183 (0xb7)
+ NA, // invokestatic = 184 (0xb8)
+ NA, // invokeinterface = 185 (0xb9)
+ NA, // invokedynamic = 186 (0xba)
+ 1, // new = 187 (0xbb)
+ 0, // newarray = 188 (0xbc)
+ 0, // anewarray = 189 (0xbd)
+ 0, // arraylength = 190 (0xbe)
+ NA, // athrow = 191 (0xbf)
+ 0, // checkcast = 192 (0xc0)
+ 0, // instanceof = 193 (0xc1)
+ -1, // monitorenter = 194 (0xc2)
+ -1, // monitorexit = 195 (0xc3)
+ NA, // wide = 196 (0xc4)
+ NA, // multianewarray = 197 (0xc5)
+ -1, // ifnull = 198 (0xc6)
+ -1, // ifnonnull = 199 (0xc7)
+ NA, // goto_w = 200 (0xc8)
+ NA // jsr_w = 201 (0xc9)
+ };
+
+ /** Where the constants used in this MethodWriter must be stored. */
+ private final SymbolTable symbolTable;
+
+ // Note: fields are ordered as in the method_info structure, and those related to attributes are
+ // ordered as in Section 4.7 of the JVMS.
+
+ /**
+ * The access_flags field of the method_info JVMS structure. This field can contain ASM specific
+ * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the
+ * ClassFile structure.
+ */
+ private final int accessFlags;
+
+ /** The name_index field of the method_info JVMS structure. */
+ private final int nameIndex;
+
+ /** The name of this method. */
+ private final String name;
+
+ /** The descriptor_index field of the method_info JVMS structure. */
+ private final int descriptorIndex;
+
+ /** The descriptor of this method. */
+ private final String descriptor;
+
+ // Code attribute fields and sub attributes:
+
+ /** The max_stack field of the Code attribute. */
+ private int maxStack;
+
+ /** The max_locals field of the Code attribute. */
+ private int maxLocals;
+
+ /** The 'code' field of the Code attribute. */
+ private final ByteVector code = new ByteVector();
+
+ /**
+ * The first element in the exception handler list (used to generate the exception_table of the
+ * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
+ * be {@literal null}.
+ */
+ private Handler firstHandler;
+
+ /**
+ * The last element in the exception handler list (used to generate the exception_table of the
+ * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
+ * be {@literal null}.
+ */
+ private Handler lastHandler;
+
+ /** The line_number_table_length field of the LineNumberTable code attribute. */
+ private int lineNumberTableLength;
+
+ /** The line_number_table array of the LineNumberTable code attribute, or {@literal null}. */
+ private ByteVector lineNumberTable;
+
+ /** The local_variable_table_length field of the LocalVariableTable code attribute. */
+ private int localVariableTableLength;
+
+ /**
+ * The local_variable_table array of the LocalVariableTable code attribute, or {@literal null}.
+ */
+ private ByteVector localVariableTable;
+
+ /** The local_variable_type_table_length field of the LocalVariableTypeTable code attribute. */
+ private int localVariableTypeTableLength;
+
+ /**
+ * The local_variable_type_table array of the LocalVariableTypeTable code attribute, or {@literal
+ * null}.
+ */
+ private ByteVector localVariableTypeTable;
+
+ /** The number_of_entries field of the StackMapTable code attribute. */
+ private int stackMapTableNumberOfEntries;
+
+ /** The 'entries' array of the StackMapTable code attribute. */
+ private ByteVector stackMapTableEntries;
+
+ /**
+ * The last runtime visible type annotation of the Code attribute. The previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastCodeRuntimeVisibleTypeAnnotation;
+
+ /**
+ * The last runtime invisible type annotation of the Code attribute. The previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastCodeRuntimeInvisibleTypeAnnotation;
+
+ /**
+ * The first non standard attribute of the Code attribute. The next ones can be accessed with the
+ * {@link Attribute#nextAttribute} field. May be {@literal null}.
+ *
+ * <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
+ * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
+ * #putMethodInfo} method writes the attributes in the order defined by this list, i.e. in the
+ * reverse order specified by the user.
+ */
+ private Attribute firstCodeAttribute;
+
+ // Other method_info attributes:
+
+ /** The number_of_exceptions field of the Exceptions attribute. */
+ private final int numberOfExceptions;
+
+ /** The exception_index_table array of the Exceptions attribute, or {@literal null}. */
+ private final int[] exceptionIndexTable;
+
+ /** The signature_index field of the Signature attribute. */
+ private final int signatureIndex;
+
+ /**
+ * The last runtime visible annotation of this method. The previous ones can be accessed with the
+ * {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleAnnotation;
+
+ /**
+ * The last runtime invisible annotation of this method. The previous ones can be accessed with
+ * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleAnnotation;
+
+ /** The number of method parameters that can have runtime visible annotations, or 0. */
+ private int visibleAnnotableParameterCount;
+
+ /**
+ * The runtime visible parameter annotations of this method. Each array element contains the last
+ * annotation of a parameter (which can be {@literal null} - the previous ones can be accessed
+ * with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}.
+ */
+ private AnnotationWriter[] lastRuntimeVisibleParameterAnnotations;
+
+ /** The number of method parameters that can have runtime visible annotations, or 0. */
+ private int invisibleAnnotableParameterCount;
+
+ /**
+ * The runtime invisible parameter annotations of this method. Each array element contains the
+ * last annotation of a parameter (which can be {@literal null} - the previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field). May be {@literal null}.
+ */
+ private AnnotationWriter[] lastRuntimeInvisibleParameterAnnotations;
+
+ /**
+ * The last runtime visible type annotation of this method. The previous ones can be accessed with
+ * the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
+
+ /**
+ * The last runtime invisible type annotation of this method. The previous ones can be accessed
+ * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
+
+ /** The default_value field of the AnnotationDefault attribute, or {@literal null}. */
+ private ByteVector defaultValue;
+
+ /** The parameters_count field of the MethodParameters attribute. */
+ private int parametersCount;
+
+ /** The 'parameters' array of the MethodParameters attribute, or {@literal null}. */
+ private ByteVector parameters;
+
+ /**
+ * The first non standard attribute of this method. The next ones can be accessed with the {@link
+ * Attribute#nextAttribute} field. May be {@literal null}.
+ *
+ * <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
+ * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
+ * #putMethodInfo} method writes the attributes in the order defined by this list, i.e. in the
+ * reverse order specified by the user.
+ */
+ private Attribute firstAttribute;
+
+ // -----------------------------------------------------------------------------------------------
+ // Fields used to compute the maximum stack size and number of locals, and the stack map frames
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Indicates what must be computed. Must be one of {@link #COMPUTE_ALL_FRAMES}, {@link
+ * #COMPUTE_INSERTED_FRAMES}, {@link COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link
+ * #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
+ */
+ private final int compute;
+
+ /**
+ * The first basic block of the method. The next ones (in bytecode offset order) can be accessed
+ * with the {@link Label#nextBasicBlock} field.
+ */
+ private Label firstBasicBlock;
+
+ /**
+ * The last basic block of the method (in bytecode offset order). This field is updated each time
+ * a basic block is encountered, and is used to append it at the end of the basic block list.
+ */
+ private Label lastBasicBlock;
+
+ /**
+ * The current basic block, i.e. the basic block of the last visited instruction. When {@link
+ * #compute} is equal to {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_ALL_FRAMES}, this
+ * field is {@literal null} for unreachable code. When {@link #compute} is equal to {@link
+ * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES} or {@link #COMPUTE_INSERTED_FRAMES}, this field stays
+ * unchanged throughout the whole method (i.e. the whole code is seen as a single basic block;
+ * indeed, the existing frames are sufficient by hypothesis to compute any intermediate frame -
+ * and the maximum stack size as well - without using any control flow graph).
+ */
+ private Label currentBasicBlock;
+
+ /**
+ * The relative stack size after the last visited instruction. This size is relative to the
+ * beginning of {@link #currentBasicBlock}, i.e. the true stack size after the last visited
+ * instruction is equal to the {@link Label#inputStackSize} of the current basic block plus {@link
+ * #relativeStackSize}. When {@link #compute} is equal to {@link
+ * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link #currentBasicBlock} is always the start of
+ * the method, so this relative size is also equal to the absolute stack size after the last
+ * visited instruction.
+ */
+ private int relativeStackSize;
+
+ /**
+ * The maximum relative stack size after the last visited instruction. This size is relative to
+ * the beginning of {@link #currentBasicBlock}, i.e. the true maximum stack size after the last
+ * visited instruction is equal to the {@link Label#inputStackSize} of the current basic block
+ * plus {@link #maxRelativeStackSize}.When {@link #compute} is equal to {@link
+ * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link #currentBasicBlock} is always the start of
+ * the method, so this relative size is also equal to the absolute maximum stack size after the
+ * last visited instruction.
+ */
+ private int maxRelativeStackSize;
+
+ /** The number of local variables in the last visited stack map frame. */
+ private int currentLocals;
+
+ /** The bytecode offset of the last frame that was written in {@link #stackMapTableEntries}. */
+ private int previousFrameOffset;
+
+ /**
+ * The last frame that was written in {@link #stackMapTableEntries}. This field has the same
+ * format as {@link #currentFrame}.
+ */
+ private int[] previousFrame;
+
+ /**
+ * The current stack map frame. The first element contains the bytecode offset of the instruction
+ * to which the frame corresponds, the second element is the number of locals and the third one is
+ * the number of stack elements. The local variables start at index 3 and are followed by the
+ * operand stack elements. In summary frame[0] = offset, frame[1] = numLocal, frame[2] = numStack.
+ * Local variables and operand stack entries contain abstract types, as defined in {@link Frame},
+ * but restricted to {@link Frame#CONSTANT_KIND}, {@link Frame#REFERENCE_KIND} or {@link
+ * Frame#UNINITIALIZED_KIND} abstract types. Long and double types use only one array entry.
+ */
+ private int[] currentFrame;
+
+ /** Whether this method contains subroutines. */
+ private boolean hasSubroutines;
+
+ // -----------------------------------------------------------------------------------------------
+ // Other miscellaneous status fields
+ // -----------------------------------------------------------------------------------------------
+
+ /** Whether the bytecode of this method contains ASM specific instructions. */
+ private boolean hasAsmInstructions;
+
+ /**
+ * The start offset of the last visited instruction. Used to set the offset field of type
+ * annotations of type 'offset_target' (see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.1">JVMS
+ * 4.7.20.1</a>).
+ */
+ private int lastBytecodeOffset;
+
+ /**
+ * The offset in bytes in {@link SymbolTable#getSource} from which the method_info for this method
+ * (excluding its first 6 bytes) must be copied, or 0.
+ */
+ private int sourceOffset;
+
+ /**
+ * The length in bytes in {@link SymbolTable#getSource} which must be copied to get the
+ * method_info for this method (excluding its first 6 bytes for access_flags, name_index and
+ * descriptor_index).
+ */
+ private int sourceLength;
+
+ // -----------------------------------------------------------------------------------------------
+ // Constructor and accessors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link MethodWriter}.
+ *
+ * @param symbolTable where the constants used in this AnnotationWriter must be stored.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param descriptor the method's descriptor (see {@link Type}).
+ * @param signature the method's signature. May be {@literal null}.
+ * @param exceptions the internal names of the method's exceptions. May be {@literal null}.
+ * @param compute indicates what must be computed (see #compute).
+ */
+ MethodWriter(
+ final SymbolTable symbolTable,
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions,
+ final int compute) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.symbolTable = symbolTable;
+ this.accessFlags = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access;
+ this.nameIndex = symbolTable.addConstantUtf8(name);
+ this.name = name;
+ this.descriptorIndex = symbolTable.addConstantUtf8(descriptor);
+ this.descriptor = descriptor;
+ this.signatureIndex = signature == null ? 0 : symbolTable.addConstantUtf8(signature);
+ if (exceptions != null && exceptions.length > 0) {
+ numberOfExceptions = exceptions.length;
+ this.exceptionIndexTable = new int[numberOfExceptions];
+ for (int i = 0; i < numberOfExceptions; ++i) {
+ this.exceptionIndexTable[i] = symbolTable.addConstantClass(exceptions[i]).index;
+ }
+ } else {
+ numberOfExceptions = 0;
+ this.exceptionIndexTable = null;
+ }
+ this.compute = compute;
+ if (compute != COMPUTE_NOTHING) {
+ // Update maxLocals and currentLocals.
+ int argumentsSize = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ --argumentsSize;
+ }
+ maxLocals = argumentsSize;
+ currentLocals = argumentsSize;
+ // Create and visit the label for the first basic block.
+ firstBasicBlock = new Label();
+ visitLabel(firstBasicBlock);
+ }
+ }
+
+ boolean hasFrames() {
+ return stackMapTableNumberOfEntries > 0;
+ }
+
+ boolean hasAsmInstructions() {
+ return hasAsmInstructions;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the MethodVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ if (parameters == null) {
+ parameters = new ByteVector();
+ }
+ ++parametersCount;
+ parameters.putShort((name == null) ? 0 : symbolTable.addConstantUtf8(name)).putShort(access);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ defaultValue = new ByteVector();
+ return new AnnotationWriter(symbolTable, /* useNamedValues = */ false, defaultValue, null);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeVisibleAnnotation);
+ } else {
+ return lastRuntimeInvisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeInvisibleAnnotation);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ if (visible) {
+ visibleAnnotableParameterCount = parameterCount;
+ } else {
+ invisibleAnnotableParameterCount = parameterCount;
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String annotationDescriptor, final boolean visible) {
+ if (visible) {
+ if (lastRuntimeVisibleParameterAnnotations == null) {
+ lastRuntimeVisibleParameterAnnotations =
+ new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ }
+ return lastRuntimeVisibleParameterAnnotations[parameter] =
+ AnnotationWriter.create(
+ symbolTable, annotationDescriptor, lastRuntimeVisibleParameterAnnotations[parameter]);
+ } else {
+ if (lastRuntimeInvisibleParameterAnnotations == null) {
+ lastRuntimeInvisibleParameterAnnotations =
+ new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ }
+ return lastRuntimeInvisibleParameterAnnotations[parameter] =
+ AnnotationWriter.create(
+ symbolTable,
+ annotationDescriptor,
+ lastRuntimeInvisibleParameterAnnotations[parameter]);
+ }
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ // Store the attributes in the <i>reverse</i> order of their visit by this method.
+ if (attribute.isCodeAttribute()) {
+ attribute.nextAttribute = firstCodeAttribute;
+ firstCodeAttribute = attribute;
+ } else {
+ attribute.nextAttribute = firstAttribute;
+ firstAttribute = attribute;
+ }
+ }
+
+ @Override
+ public void visitCode() {
+ // Nothing to do.
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ if (compute == COMPUTE_ALL_FRAMES) {
+ return;
+ }
+
+ if (compute == COMPUTE_INSERTED_FRAMES) {
+ if (currentBasicBlock.frame == null) {
+ // This should happen only once, for the implicit first frame (which is explicitly visited
+ // in ClassReader if the EXPAND_ASM_INSNS option is used - and COMPUTE_INSERTED_FRAMES
+ // can't be set if EXPAND_ASM_INSNS is not used).
+ currentBasicBlock.frame = new CurrentFrame(currentBasicBlock);
+ currentBasicBlock.frame.setInputFrameFromDescriptor(
+ symbolTable, accessFlags, descriptor, numLocal);
+ currentBasicBlock.frame.accept(this);
+ } else {
+ if (type == Opcodes.F_NEW) {
+ currentBasicBlock.frame.setInputFrameFromApiFormat(
+ symbolTable, numLocal, local, numStack, stack);
+ }
+ // If type is not F_NEW then it is F_INSERT by hypothesis, and currentBlock.frame contains
+ // the stack map frame at the current instruction, computed from the last F_NEW frame and
+ // the bytecode instructions in between (via calls to CurrentFrame#execute).
+ currentBasicBlock.frame.accept(this);
+ }
+ } else if (type == Opcodes.F_NEW) {
+ if (previousFrame == null) {
+ int argumentsSize = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
+ Frame implicitFirstFrame = new Frame(new Label());
+ implicitFirstFrame.setInputFrameFromDescriptor(
+ symbolTable, accessFlags, descriptor, argumentsSize);
+ implicitFirstFrame.accept(this);
+ }
+ currentLocals = numLocal;
+ int frameIndex = visitFrameStart(code.length, numLocal, numStack);
+ for (int i = 0; i < numLocal; ++i) {
+ currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, local[i]);
+ }
+ for (int i = 0; i < numStack; ++i) {
+ currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, stack[i]);
+ }
+ visitFrameEnd();
+ } else {
+ if (symbolTable.getMajorVersion() < Opcodes.V1_6) {
+ throw new IllegalArgumentException("Class versions V1_5 or less must use F_NEW frames.");
+ }
+ int offsetDelta;
+ if (stackMapTableEntries == null) {
+ stackMapTableEntries = new ByteVector();
+ offsetDelta = code.length;
+ } else {
+ offsetDelta = code.length - previousFrameOffset - 1;
+ if (offsetDelta < 0) {
+ if (type == Opcodes.F_SAME) {
+ return;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ switch (type) {
+ case Opcodes.F_FULL:
+ currentLocals = numLocal;
+ stackMapTableEntries.putByte(Frame.FULL_FRAME).putShort(offsetDelta).putShort(numLocal);
+ for (int i = 0; i < numLocal; ++i) {
+ putFrameType(local[i]);
+ }
+ stackMapTableEntries.putShort(numStack);
+ for (int i = 0; i < numStack; ++i) {
+ putFrameType(stack[i]);
+ }
+ break;
+ case Opcodes.F_APPEND:
+ currentLocals += numLocal;
+ stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED + numLocal).putShort(offsetDelta);
+ for (int i = 0; i < numLocal; ++i) {
+ putFrameType(local[i]);
+ }
+ break;
+ case Opcodes.F_CHOP:
+ currentLocals -= numLocal;
+ stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED - numLocal).putShort(offsetDelta);
+ break;
+ case Opcodes.F_SAME:
+ if (offsetDelta < 64) {
+ stackMapTableEntries.putByte(offsetDelta);
+ } else {
+ stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED).putShort(offsetDelta);
+ }
+ break;
+ case Opcodes.F_SAME1:
+ if (offsetDelta < 64) {
+ stackMapTableEntries.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta);
+ } else {
+ stackMapTableEntries
+ .putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
+ .putShort(offsetDelta);
+ }
+ putFrameType(stack[0]);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ previousFrameOffset = code.length;
+ ++stackMapTableNumberOfEntries;
+ }
+
+ if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES) {
+ relativeStackSize = numStack;
+ for (int i = 0; i < numStack; ++i) {
+ if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
+ relativeStackSize++;
+ }
+ }
+ if (relativeStackSize > maxRelativeStackSize) {
+ maxRelativeStackSize = relativeStackSize;
+ }
+ }
+
+ maxStack = Math.max(maxStack, numStack);
+ maxLocals = Math.max(maxLocals, currentLocals);
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ code.putByte(opcode);
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, 0, null, null);
+ } else {
+ int size = relativeStackSize + STACK_SIZE_DELTA[opcode];
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
+ endCurrentBasicBlockWithNoSuccessor();
+ }
+ }
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ if (opcode == Opcodes.SIPUSH) {
+ code.put12(opcode, operand);
+ } else { // BIPUSH or NEWARRAY
+ code.put11(opcode, operand);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, operand, null, null);
+ } else if (opcode != Opcodes.NEWARRAY) {
+ // The stack size delta is 1 for BIPUSH or SIPUSH, and 0 for NEWARRAY.
+ int size = relativeStackSize + 1;
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ if (varIndex < 4 && opcode != Opcodes.RET) {
+ int optimizedOpcode;
+ if (opcode < Opcodes.ISTORE) {
+ optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + varIndex;
+ } else {
+ optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + varIndex;
+ }
+ code.putByte(optimizedOpcode);
+ } else if (varIndex >= 256) {
+ code.putByte(Constants.WIDE).put12(opcode, varIndex);
+ } else {
+ code.put11(opcode, varIndex);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, varIndex, null, null);
+ } else {
+ if (opcode == Opcodes.RET) {
+ // No stack size delta.
+ currentBasicBlock.flags |= Label.FLAG_SUBROUTINE_END;
+ currentBasicBlock.outputStackSize = (short) relativeStackSize;
+ endCurrentBasicBlockWithNoSuccessor();
+ } else { // xLOAD or xSTORE
+ int size = relativeStackSize + STACK_SIZE_DELTA[opcode];
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+ if (compute != COMPUTE_NOTHING) {
+ int currentMaxLocals;
+ if (opcode == Opcodes.LLOAD
+ || opcode == Opcodes.DLOAD
+ || opcode == Opcodes.LSTORE
+ || opcode == Opcodes.DSTORE) {
+ currentMaxLocals = varIndex + 2;
+ } else {
+ currentMaxLocals = varIndex + 1;
+ }
+ if (currentMaxLocals > maxLocals) {
+ maxLocals = currentMaxLocals;
+ }
+ }
+ if (opcode >= Opcodes.ISTORE && compute == COMPUTE_ALL_FRAMES && firstHandler != null) {
+ // If there are exception handler blocks, each instruction within a handler range is, in
+ // theory, a basic block (since execution can jump from this instruction to the exception
+ // handler). As a consequence, the local variable types at the beginning of the handler
+ // block should be the merge of the local variable types at all the instructions within the
+ // handler range. However, instead of creating a basic block for each instruction, we can
+ // get the same result in a more efficient way. Namely, by starting a new basic block after
+ // each xSTORE instruction, which is what we do here.
+ visitLabel(new Label());
+ }
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol typeSymbol = symbolTable.addConstantClass(type);
+ code.put12(opcode, typeSymbol.index);
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, lastBytecodeOffset, typeSymbol, symbolTable);
+ } else if (opcode == Opcodes.NEW) {
+ // The stack size delta is 1 for NEW, and 0 for ANEWARRAY, CHECKCAST, or INSTANCEOF.
+ int size = relativeStackSize + 1;
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol fieldrefSymbol = symbolTable.addConstantFieldref(owner, name, descriptor);
+ code.put12(opcode, fieldrefSymbol.index);
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, 0, fieldrefSymbol, symbolTable);
+ } else {
+ int size;
+ char firstDescChar = descriptor.charAt(0);
+ switch (opcode) {
+ case Opcodes.GETSTATIC:
+ size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 2 : 1);
+ break;
+ case Opcodes.PUTSTATIC:
+ size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -2 : -1);
+ break;
+ case Opcodes.GETFIELD:
+ size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? 1 : 0);
+ break;
+ case Opcodes.PUTFIELD:
+ default:
+ size = relativeStackSize + (firstDescChar == 'D' || firstDescChar == 'J' ? -3 : -2);
+ break;
+ }
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol methodrefSymbol = symbolTable.addConstantMethodref(owner, name, descriptor, isInterface);
+ if (opcode == Opcodes.INVOKEINTERFACE) {
+ code.put12(Opcodes.INVOKEINTERFACE, methodrefSymbol.index)
+ .put11(methodrefSymbol.getArgumentsAndReturnSizes() >> 2, 0);
+ } else {
+ code.put12(opcode, methodrefSymbol.index);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(opcode, 0, methodrefSymbol, symbolTable);
+ } else {
+ int argumentsAndReturnSize = methodrefSymbol.getArgumentsAndReturnSizes();
+ int stackSizeDelta = (argumentsAndReturnSize & 3) - (argumentsAndReturnSize >> 2);
+ int size;
+ if (opcode == Opcodes.INVOKESTATIC) {
+ size = relativeStackSize + stackSizeDelta + 1;
+ } else {
+ size = relativeStackSize + stackSizeDelta;
+ }
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol invokeDynamicSymbol =
+ symbolTable.addConstantInvokeDynamic(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ code.put12(Opcodes.INVOKEDYNAMIC, invokeDynamicSymbol.index);
+ code.putShort(0);
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, invokeDynamicSymbol, symbolTable);
+ } else {
+ int argumentsAndReturnSize = invokeDynamicSymbol.getArgumentsAndReturnSizes();
+ int stackSizeDelta = (argumentsAndReturnSize & 3) - (argumentsAndReturnSize >> 2) + 1;
+ int size = relativeStackSize + stackSizeDelta;
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ // Compute the 'base' opcode, i.e. GOTO or JSR if opcode is GOTO_W or JSR_W, otherwise opcode.
+ int baseOpcode =
+ opcode >= Constants.GOTO_W ? opcode - Constants.WIDE_JUMP_OPCODE_DELTA : opcode;
+ boolean nextInsnIsJumpTarget = false;
+ if ((label.flags & Label.FLAG_RESOLVED) != 0
+ && label.bytecodeOffset - code.length < Short.MIN_VALUE) {
+ // Case of a backward jump with an offset < -32768. In this case we automatically replace GOTO
+ // with GOTO_W, JSR with JSR_W and IFxxx <l> with IFNOTxxx <L> GOTO_W <l> L:..., where
+ // IFNOTxxx is the "opposite" opcode of IFxxx (e.g. IFNE for IFEQ) and where <L> designates
+ // the instruction just after the GOTO_W.
+ if (baseOpcode == Opcodes.GOTO) {
+ code.putByte(Constants.GOTO_W);
+ } else if (baseOpcode == Opcodes.JSR) {
+ code.putByte(Constants.JSR_W);
+ } else {
+ // Put the "opposite" opcode of baseOpcode. This can be done by flipping the least
+ // significant bit for IFNULL and IFNONNULL, and similarly for IFEQ ... IF_ACMPEQ (with a
+ // pre and post offset by 1). The jump offset is 8 bytes (3 for IFNOTxxx, 5 for GOTO_W).
+ code.putByte(baseOpcode >= Opcodes.IFNULL ? baseOpcode ^ 1 : ((baseOpcode + 1) ^ 1) - 1);
+ code.putShort(8);
+ // Here we could put a GOTO_W in theory, but if ASM specific instructions are used in this
+ // method or another one, and if the class has frames, we will need to insert a frame after
+ // this GOTO_W during the additional ClassReader -> ClassWriter round trip to remove the ASM
+ // specific instructions. To not miss this additional frame, we need to use an ASM_GOTO_W
+ // here, which has the unfortunate effect of forcing this additional round trip (which in
+ // some case would not have been really necessary, but we can't know this at this point).
+ code.putByte(Constants.ASM_GOTO_W);
+ hasAsmInstructions = true;
+ // The instruction after the GOTO_W becomes the target of the IFNOT instruction.
+ nextInsnIsJumpTarget = true;
+ }
+ label.put(code, code.length - 1, true);
+ } else if (baseOpcode != opcode) {
+ // Case of a GOTO_W or JSR_W specified by the user (normally ClassReader when used to remove
+ // ASM specific instructions). In this case we keep the original instruction.
+ code.putByte(opcode);
+ label.put(code, code.length - 1, true);
+ } else {
+ // Case of a jump with an offset >= -32768, or of a jump with an unknown offset. In these
+ // cases we store the offset in 2 bytes (which will be increased via a ClassReader ->
+ // ClassWriter round trip if it turns out that 2 bytes are not sufficient).
+ code.putByte(baseOpcode);
+ label.put(code, code.length - 1, false);
+ }
+
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ Label nextBasicBlock = null;
+ if (compute == COMPUTE_ALL_FRAMES) {
+ currentBasicBlock.frame.execute(baseOpcode, 0, null, null);
+ // Record the fact that 'label' is the target of a jump instruction.
+ label.getCanonicalInstance().flags |= Label.FLAG_JUMP_TARGET;
+ // Add 'label' as a successor of the current basic block.
+ addSuccessorToCurrentBasicBlock(Edge.JUMP, label);
+ if (baseOpcode != Opcodes.GOTO) {
+ // The next instruction starts a new basic block (except for GOTO: by default the code
+ // following a goto is unreachable - unless there is an explicit label for it - and we
+ // should not compute stack frame types for its instructions).
+ nextBasicBlock = new Label();
+ }
+ } else if (compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(baseOpcode, 0, null, null);
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES) {
+ // No need to update maxRelativeStackSize (the stack size delta is always negative).
+ relativeStackSize += STACK_SIZE_DELTA[baseOpcode];
+ } else {
+ if (baseOpcode == Opcodes.JSR) {
+ // Record the fact that 'label' designates a subroutine, if not already done.
+ if ((label.flags & Label.FLAG_SUBROUTINE_START) == 0) {
+ label.flags |= Label.FLAG_SUBROUTINE_START;
+ hasSubroutines = true;
+ }
+ currentBasicBlock.flags |= Label.FLAG_SUBROUTINE_CALLER;
+ // Note that, by construction in this method, a block which calls a subroutine has at
+ // least two successors in the control flow graph: the first one (added below) leads to
+ // the instruction after the JSR, while the second one (added here) leads to the JSR
+ // target. Note that the first successor is virtual (it does not correspond to a possible
+ // execution path): it is only used to compute the successors of the basic blocks ending
+ // with a ret, in {@link Label#addSubroutineRetSuccessors}.
+ addSuccessorToCurrentBasicBlock(relativeStackSize + 1, label);
+ // The instruction after the JSR starts a new basic block.
+ nextBasicBlock = new Label();
+ } else {
+ // No need to update maxRelativeStackSize (the stack size delta is always negative).
+ relativeStackSize += STACK_SIZE_DELTA[baseOpcode];
+ addSuccessorToCurrentBasicBlock(relativeStackSize, label);
+ }
+ }
+ // If the next instruction starts a new basic block, call visitLabel to add the label of this
+ // instruction as a successor of the current block, and to start a new basic block.
+ if (nextBasicBlock != null) {
+ if (nextInsnIsJumpTarget) {
+ nextBasicBlock.flags |= Label.FLAG_JUMP_TARGET;
+ }
+ visitLabel(nextBasicBlock);
+ }
+ if (baseOpcode == Opcodes.GOTO) {
+ endCurrentBasicBlockWithNoSuccessor();
+ }
+ }
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ // Resolve the forward references to this label, if any.
+ hasAsmInstructions |= label.resolve(code.data, code.length);
+ // visitLabel starts a new basic block (except for debug only labels), so we need to update the
+ // previous and current block references and list of successors.
+ if ((label.flags & Label.FLAG_DEBUG_ONLY) != 0) {
+ return;
+ }
+ if (compute == COMPUTE_ALL_FRAMES) {
+ if (currentBasicBlock != null) {
+ if (label.bytecodeOffset == currentBasicBlock.bytecodeOffset) {
+ // We use {@link Label#getCanonicalInstance} to store the state of a basic block in only
+ // one place, but this does not work for labels which have not been visited yet.
+ // Therefore, when we detect here two labels having the same bytecode offset, we need to
+ // - consolidate the state scattered in these two instances into the canonical instance:
+ currentBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET);
+ // - make sure the two instances share the same Frame instance (the implementation of
+ // {@link Label#getCanonicalInstance} relies on this property; here label.frame should be
+ // null):
+ label.frame = currentBasicBlock.frame;
+ // - and make sure to NOT assign 'label' into 'currentBasicBlock' or 'lastBasicBlock', so
+ // that they still refer to the canonical instance for this bytecode offset.
+ return;
+ }
+ // End the current basic block (with one new successor).
+ addSuccessorToCurrentBasicBlock(Edge.JUMP, label);
+ }
+ // Append 'label' at the end of the basic block list.
+ if (lastBasicBlock != null) {
+ if (label.bytecodeOffset == lastBasicBlock.bytecodeOffset) {
+ // Same comment as above.
+ lastBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET);
+ // Here label.frame should be null.
+ label.frame = lastBasicBlock.frame;
+ currentBasicBlock = lastBasicBlock;
+ return;
+ }
+ lastBasicBlock.nextBasicBlock = label;
+ }
+ lastBasicBlock = label;
+ // Make it the new current basic block.
+ currentBasicBlock = label;
+ // Here label.frame should be null.
+ label.frame = new Frame(label);
+ } else if (compute == COMPUTE_INSERTED_FRAMES) {
+ if (currentBasicBlock == null) {
+ // This case should happen only once, for the visitLabel call in the constructor. Indeed, if
+ // compute is equal to COMPUTE_INSERTED_FRAMES, currentBasicBlock stays unchanged.
+ currentBasicBlock = label;
+ } else {
+ // Update the frame owner so that a correct frame offset is computed in Frame.accept().
+ currentBasicBlock.frame.owner = label;
+ }
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
+ if (currentBasicBlock != null) {
+ // End the current basic block (with one new successor).
+ currentBasicBlock.outputStackMax = (short) maxRelativeStackSize;
+ addSuccessorToCurrentBasicBlock(relativeStackSize, label);
+ }
+ // Start a new current basic block, and reset the current and maximum relative stack sizes.
+ currentBasicBlock = label;
+ relativeStackSize = 0;
+ maxRelativeStackSize = 0;
+ // Append the new basic block at the end of the basic block list.
+ if (lastBasicBlock != null) {
+ lastBasicBlock.nextBasicBlock = label;
+ }
+ lastBasicBlock = label;
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES && currentBasicBlock == null) {
+ // This case should happen only once, for the visitLabel call in the constructor. Indeed, if
+ // compute is equal to COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES, currentBasicBlock stays
+ // unchanged.
+ currentBasicBlock = label;
+ }
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol constantSymbol = symbolTable.addConstant(value);
+ int constantIndex = constantSymbol.index;
+ char firstDescriptorChar;
+ boolean isLongOrDouble =
+ constantSymbol.tag == Symbol.CONSTANT_LONG_TAG
+ || constantSymbol.tag == Symbol.CONSTANT_DOUBLE_TAG
+ || (constantSymbol.tag == Symbol.CONSTANT_DYNAMIC_TAG
+ && ((firstDescriptorChar = constantSymbol.value.charAt(0)) == 'J'
+ || firstDescriptorChar == 'D'));
+ if (isLongOrDouble) {
+ code.put12(Constants.LDC2_W, constantIndex);
+ } else if (constantIndex >= 256) {
+ code.put12(Constants.LDC_W, constantIndex);
+ } else {
+ code.put11(Opcodes.LDC, constantIndex);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(Opcodes.LDC, 0, constantSymbol, symbolTable);
+ } else {
+ int size = relativeStackSize + (isLongOrDouble ? 2 : 1);
+ if (size > maxRelativeStackSize) {
+ maxRelativeStackSize = size;
+ }
+ relativeStackSize = size;
+ }
+ }
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ if ((varIndex > 255) || (increment > 127) || (increment < -128)) {
+ code.putByte(Constants.WIDE).put12(Opcodes.IINC, varIndex).putShort(increment);
+ } else {
+ code.putByte(Opcodes.IINC).put11(varIndex, increment);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null
+ && (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES)) {
+ currentBasicBlock.frame.execute(Opcodes.IINC, varIndex, null, null);
+ }
+ if (compute != COMPUTE_NOTHING) {
+ int currentMaxLocals = varIndex + 1;
+ if (currentMaxLocals > maxLocals) {
+ maxLocals = currentMaxLocals;
+ }
+ }
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ code.putByte(Opcodes.TABLESWITCH).putByteArray(null, 0, (4 - code.length % 4) % 4);
+ dflt.put(code, lastBytecodeOffset, true);
+ code.putInt(min).putInt(max);
+ for (Label label : labels) {
+ label.put(code, lastBytecodeOffset, true);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ visitSwitchInsn(dflt, labels);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ code.putByte(Opcodes.LOOKUPSWITCH).putByteArray(null, 0, (4 - code.length % 4) % 4);
+ dflt.put(code, lastBytecodeOffset, true);
+ code.putInt(labels.length);
+ for (int i = 0; i < labels.length; ++i) {
+ code.putInt(keys[i]);
+ labels[i].put(code, lastBytecodeOffset, true);
+ }
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ visitSwitchInsn(dflt, labels);
+ }
+
+ private void visitSwitchInsn(final Label dflt, final Label[] labels) {
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES) {
+ currentBasicBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null);
+ // Add all the labels as successors of the current basic block.
+ addSuccessorToCurrentBasicBlock(Edge.JUMP, dflt);
+ dflt.getCanonicalInstance().flags |= Label.FLAG_JUMP_TARGET;
+ for (Label label : labels) {
+ addSuccessorToCurrentBasicBlock(Edge.JUMP, label);
+ label.getCanonicalInstance().flags |= Label.FLAG_JUMP_TARGET;
+ }
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
+ // No need to update maxRelativeStackSize (the stack size delta is always negative).
+ --relativeStackSize;
+ // Add all the labels as successors of the current basic block.
+ addSuccessorToCurrentBasicBlock(relativeStackSize, dflt);
+ for (Label label : labels) {
+ addSuccessorToCurrentBasicBlock(relativeStackSize, label);
+ }
+ }
+ // End the current basic block.
+ endCurrentBasicBlockWithNoSuccessor();
+ }
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ lastBytecodeOffset = code.length;
+ // Add the instruction to the bytecode of the method.
+ Symbol descSymbol = symbolTable.addConstantClass(descriptor);
+ code.put12(Opcodes.MULTIANEWARRAY, descSymbol.index).putByte(numDimensions);
+ // If needed, update the maximum stack size and number of locals, and stack map frames.
+ if (currentBasicBlock != null) {
+ if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
+ currentBasicBlock.frame.execute(
+ Opcodes.MULTIANEWARRAY, numDimensions, descSymbol, symbolTable);
+ } else {
+ // No need to update maxRelativeStackSize (the stack size delta is always negative).
+ relativeStackSize += 1 - numDimensions;
+ }
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastCodeRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable,
+ (typeRef & 0xFF0000FF) | (lastBytecodeOffset << 8),
+ typePath,
+ descriptor,
+ lastCodeRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastCodeRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable,
+ (typeRef & 0xFF0000FF) | (lastBytecodeOffset << 8),
+ typePath,
+ descriptor,
+ lastCodeRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ Handler newHandler =
+ new Handler(
+ start, end, handler, type != null ? symbolTable.addConstantClass(type).index : 0, type);
+ if (firstHandler == null) {
+ firstHandler = newHandler;
+ } else {
+ lastHandler.nextHandler = newHandler;
+ }
+ lastHandler = newHandler;
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastCodeRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastCodeRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastCodeRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastCodeRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ if (signature != null) {
+ if (localVariableTypeTable == null) {
+ localVariableTypeTable = new ByteVector();
+ }
+ ++localVariableTypeTableLength;
+ localVariableTypeTable
+ .putShort(start.bytecodeOffset)
+ .putShort(end.bytecodeOffset - start.bytecodeOffset)
+ .putShort(symbolTable.addConstantUtf8(name))
+ .putShort(symbolTable.addConstantUtf8(signature))
+ .putShort(index);
+ }
+ if (localVariableTable == null) {
+ localVariableTable = new ByteVector();
+ }
+ ++localVariableTableLength;
+ localVariableTable
+ .putShort(start.bytecodeOffset)
+ .putShort(end.bytecodeOffset - start.bytecodeOffset)
+ .putShort(symbolTable.addConstantUtf8(name))
+ .putShort(symbolTable.addConstantUtf8(descriptor))
+ .putShort(index);
+ if (compute != COMPUTE_NOTHING) {
+ char firstDescChar = descriptor.charAt(0);
+ int currentMaxLocals = index + (firstDescChar == 'J' || firstDescChar == 'D' ? 2 : 1);
+ if (currentMaxLocals > maxLocals) {
+ maxLocals = currentMaxLocals;
+ }
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ // Create a ByteVector to hold a 'type_annotation' JVMS structure.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.
+ ByteVector typeAnnotation = new ByteVector();
+ // Write target_type, target_info, and target_path.
+ typeAnnotation.putByte(typeRef >>> 24).putShort(start.length);
+ for (int i = 0; i < start.length; ++i) {
+ typeAnnotation
+ .putShort(start[i].bytecodeOffset)
+ .putShort(end[i].bytecodeOffset - start[i].bytecodeOffset)
+ .putShort(index[i]);
+ }
+ TypePath.put(typePath, typeAnnotation);
+ // Write type_index and reserve space for num_element_value_pairs.
+ typeAnnotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0);
+ if (visible) {
+ return lastCodeRuntimeVisibleTypeAnnotation =
+ new AnnotationWriter(
+ symbolTable,
+ /* useNamedValues = */ true,
+ typeAnnotation,
+ lastCodeRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastCodeRuntimeInvisibleTypeAnnotation =
+ new AnnotationWriter(
+ symbolTable,
+ /* useNamedValues = */ true,
+ typeAnnotation,
+ lastCodeRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ if (lineNumberTable == null) {
+ lineNumberTable = new ByteVector();
+ }
+ ++lineNumberTableLength;
+ lineNumberTable.putShort(start.bytecodeOffset);
+ lineNumberTable.putShort(line);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ if (compute == COMPUTE_ALL_FRAMES) {
+ computeAllFrames();
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
+ computeMaxStackAndLocal();
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES) {
+ this.maxStack = maxRelativeStackSize;
+ } else {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+ }
+
+ /** Computes all the stack map frames of the method, from scratch. */
+ private void computeAllFrames() {
+ // Complete the control flow graph with exception handler blocks.
+ Handler handler = firstHandler;
+ while (handler != null) {
+ String catchTypeDescriptor =
+ handler.catchTypeDescriptor == null ? "java/lang/Throwable" : handler.catchTypeDescriptor;
+ int catchType = Frame.getAbstractTypeFromInternalName(symbolTable, catchTypeDescriptor);
+ // Mark handlerBlock as an exception handler.
+ Label handlerBlock = handler.handlerPc.getCanonicalInstance();
+ handlerBlock.flags |= Label.FLAG_JUMP_TARGET;
+ // Add handlerBlock as a successor of all the basic blocks in the exception handler range.
+ Label handlerRangeBlock = handler.startPc.getCanonicalInstance();
+ Label handlerRangeEnd = handler.endPc.getCanonicalInstance();
+ while (handlerRangeBlock != handlerRangeEnd) {
+ handlerRangeBlock.outgoingEdges =
+ new Edge(catchType, handlerBlock, handlerRangeBlock.outgoingEdges);
+ handlerRangeBlock = handlerRangeBlock.nextBasicBlock;
+ }
+ handler = handler.nextHandler;
+ }
+
+ // Create and visit the first (implicit) frame.
+ Frame firstFrame = firstBasicBlock.frame;
+ firstFrame.setInputFrameFromDescriptor(symbolTable, accessFlags, descriptor, this.maxLocals);
+ firstFrame.accept(this);
+
+ // Fix point algorithm: add the first basic block to a list of blocks to process (i.e. blocks
+ // whose stack map frame has changed) and, while there are blocks to process, remove one from
+ // the list and update the stack map frames of its successor blocks in the control flow graph
+ // (which might change them, in which case these blocks must be processed too, and are thus
+ // added to the list of blocks to process). Also compute the maximum stack size of the method,
+ // as a by-product.
+ Label listOfBlocksToProcess = firstBasicBlock;
+ listOfBlocksToProcess.nextListElement = Label.EMPTY_LIST;
+ int maxStackSize = 0;
+ while (listOfBlocksToProcess != Label.EMPTY_LIST) {
+ // Remove a basic block from the list of blocks to process.
+ Label basicBlock = listOfBlocksToProcess;
+ listOfBlocksToProcess = listOfBlocksToProcess.nextListElement;
+ basicBlock.nextListElement = null;
+ // By definition, basicBlock is reachable.
+ basicBlock.flags |= Label.FLAG_REACHABLE;
+ // Update the (absolute) maximum stack size.
+ int maxBlockStackSize = basicBlock.frame.getInputStackSize() + basicBlock.outputStackMax;
+ if (maxBlockStackSize > maxStackSize) {
+ maxStackSize = maxBlockStackSize;
+ }
+ // Update the successor blocks of basicBlock in the control flow graph.
+ Edge outgoingEdge = basicBlock.outgoingEdges;
+ while (outgoingEdge != null) {
+ Label successorBlock = outgoingEdge.successor.getCanonicalInstance();
+ boolean successorBlockChanged =
+ basicBlock.frame.merge(symbolTable, successorBlock.frame, outgoingEdge.info);
+ if (successorBlockChanged && successorBlock.nextListElement == null) {
+ // If successorBlock has changed it must be processed. Thus, if it is not already in the
+ // list of blocks to process, add it to this list.
+ successorBlock.nextListElement = listOfBlocksToProcess;
+ listOfBlocksToProcess = successorBlock;
+ }
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ }
+
+ // Loop over all the basic blocks and visit the stack map frames that must be stored in the
+ // StackMapTable attribute. Also replace unreachable code with NOP* ATHROW, and remove it from
+ // exception handler ranges.
+ Label basicBlock = firstBasicBlock;
+ while (basicBlock != null) {
+ if ((basicBlock.flags & (Label.FLAG_JUMP_TARGET | Label.FLAG_REACHABLE))
+ == (Label.FLAG_JUMP_TARGET | Label.FLAG_REACHABLE)) {
+ basicBlock.frame.accept(this);
+ }
+ if ((basicBlock.flags & Label.FLAG_REACHABLE) == 0) {
+ // Find the start and end bytecode offsets of this unreachable block.
+ Label nextBasicBlock = basicBlock.nextBasicBlock;
+ int startOffset = basicBlock.bytecodeOffset;
+ int endOffset = (nextBasicBlock == null ? code.length : nextBasicBlock.bytecodeOffset) - 1;
+ if (endOffset >= startOffset) {
+ // Replace its instructions with NOP ... NOP ATHROW.
+ for (int i = startOffset; i < endOffset; ++i) {
+ code.data[i] = Opcodes.NOP;
+ }
+ code.data[endOffset] = (byte) Opcodes.ATHROW;
+ // Emit a frame for this unreachable block, with no local and a Throwable on the stack
+ // (so that the ATHROW could consume this Throwable if it were reachable).
+ int frameIndex = visitFrameStart(startOffset, /* numLocal = */ 0, /* numStack = */ 1);
+ currentFrame[frameIndex] =
+ Frame.getAbstractTypeFromInternalName(symbolTable, "java/lang/Throwable");
+ visitFrameEnd();
+ // Remove this unreachable basic block from the exception handler ranges.
+ firstHandler = Handler.removeRange(firstHandler, basicBlock, nextBasicBlock);
+ // The maximum stack size is now at least one, because of the Throwable declared above.
+ maxStackSize = Math.max(maxStackSize, 1);
+ }
+ }
+ basicBlock = basicBlock.nextBasicBlock;
+ }
+
+ this.maxStack = maxStackSize;
+ }
+
+ /** Computes the maximum stack size of the method. */
+ private void computeMaxStackAndLocal() {
+ // Complete the control flow graph with exception handler blocks.
+ Handler handler = firstHandler;
+ while (handler != null) {
+ Label handlerBlock = handler.handlerPc;
+ Label handlerRangeBlock = handler.startPc;
+ Label handlerRangeEnd = handler.endPc;
+ // Add handlerBlock as a successor of all the basic blocks in the exception handler range.
+ while (handlerRangeBlock != handlerRangeEnd) {
+ if ((handlerRangeBlock.flags & Label.FLAG_SUBROUTINE_CALLER) == 0) {
+ handlerRangeBlock.outgoingEdges =
+ new Edge(Edge.EXCEPTION, handlerBlock, handlerRangeBlock.outgoingEdges);
+ } else {
+ // If handlerRangeBlock is a JSR block, add handlerBlock after the first two outgoing
+ // edges to preserve the hypothesis about JSR block successors order (see
+ // {@link #visitJumpInsn}).
+ handlerRangeBlock.outgoingEdges.nextEdge.nextEdge =
+ new Edge(
+ Edge.EXCEPTION, handlerBlock, handlerRangeBlock.outgoingEdges.nextEdge.nextEdge);
+ }
+ handlerRangeBlock = handlerRangeBlock.nextBasicBlock;
+ }
+ handler = handler.nextHandler;
+ }
+
+ // Complete the control flow graph with the successor blocks of subroutines, if needed.
+ if (hasSubroutines) {
+ // First step: find the subroutines. This step determines, for each basic block, to which
+ // subroutine(s) it belongs. Start with the main "subroutine":
+ short numSubroutines = 1;
+ firstBasicBlock.markSubroutine(numSubroutines);
+ // Then, mark the subroutines called by the main subroutine, then the subroutines called by
+ // those called by the main subroutine, etc.
+ for (short currentSubroutine = 1; currentSubroutine <= numSubroutines; ++currentSubroutine) {
+ Label basicBlock = firstBasicBlock;
+ while (basicBlock != null) {
+ if ((basicBlock.flags & Label.FLAG_SUBROUTINE_CALLER) != 0
+ && basicBlock.subroutineId == currentSubroutine) {
+ Label jsrTarget = basicBlock.outgoingEdges.nextEdge.successor;
+ if (jsrTarget.subroutineId == 0) {
+ // If this subroutine has not been marked yet, find its basic blocks.
+ jsrTarget.markSubroutine(++numSubroutines);
+ }
+ }
+ basicBlock = basicBlock.nextBasicBlock;
+ }
+ }
+ // Second step: find the successors in the control flow graph of each subroutine basic block
+ // 'r' ending with a RET instruction. These successors are the virtual successors of the basic
+ // blocks ending with JSR instructions (see {@link #visitJumpInsn)} that can reach 'r'.
+ Label basicBlock = firstBasicBlock;
+ while (basicBlock != null) {
+ if ((basicBlock.flags & Label.FLAG_SUBROUTINE_CALLER) != 0) {
+ // By construction, jsr targets are stored in the second outgoing edge of basic blocks
+ // that ends with a jsr instruction (see {@link #FLAG_SUBROUTINE_CALLER}).
+ Label subroutine = basicBlock.outgoingEdges.nextEdge.successor;
+ subroutine.addSubroutineRetSuccessors(basicBlock);
+ }
+ basicBlock = basicBlock.nextBasicBlock;
+ }
+ }
+
+ // Data flow algorithm: put the first basic block in a list of blocks to process (i.e. blocks
+ // whose input stack size has changed) and, while there are blocks to process, remove one
+ // from the list, update the input stack size of its successor blocks in the control flow
+ // graph, and add these blocks to the list of blocks to process (if not already done).
+ Label listOfBlocksToProcess = firstBasicBlock;
+ listOfBlocksToProcess.nextListElement = Label.EMPTY_LIST;
+ int maxStackSize = maxStack;
+ while (listOfBlocksToProcess != Label.EMPTY_LIST) {
+ // Remove a basic block from the list of blocks to process. Note that we don't reset
+ // basicBlock.nextListElement to null on purpose, to make sure we don't reprocess already
+ // processed basic blocks.
+ Label basicBlock = listOfBlocksToProcess;
+ listOfBlocksToProcess = listOfBlocksToProcess.nextListElement;
+ // Compute the (absolute) input stack size and maximum stack size of this block.
+ int inputStackTop = basicBlock.inputStackSize;
+ int maxBlockStackSize = inputStackTop + basicBlock.outputStackMax;
+ // Update the absolute maximum stack size of the method.
+ if (maxBlockStackSize > maxStackSize) {
+ maxStackSize = maxBlockStackSize;
+ }
+ // Update the input stack size of the successor blocks of basicBlock in the control flow
+ // graph, and add these blocks to the list of blocks to process, if not already done.
+ Edge outgoingEdge = basicBlock.outgoingEdges;
+ if ((basicBlock.flags & Label.FLAG_SUBROUTINE_CALLER) != 0) {
+ // Ignore the first outgoing edge of the basic blocks ending with a jsr: these are virtual
+ // edges which lead to the instruction just after the jsr, and do not correspond to a
+ // possible execution path (see {@link #visitJumpInsn} and
+ // {@link Label#FLAG_SUBROUTINE_CALLER}).
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ while (outgoingEdge != null) {
+ Label successorBlock = outgoingEdge.successor;
+ if (successorBlock.nextListElement == null) {
+ successorBlock.inputStackSize =
+ (short) (outgoingEdge.info == Edge.EXCEPTION ? 1 : inputStackTop + outgoingEdge.info);
+ successorBlock.nextListElement = listOfBlocksToProcess;
+ listOfBlocksToProcess = successorBlock;
+ }
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ }
+ this.maxStack = maxStackSize;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods: control flow analysis algorithm
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds a successor to {@link #currentBasicBlock} in the control flow graph.
+ *
+ * @param info information about the control flow edge to be added.
+ * @param successor the successor block to be added to the current basic block.
+ */
+ private void addSuccessorToCurrentBasicBlock(final int info, final Label successor) {
+ currentBasicBlock.outgoingEdges = new Edge(info, successor, currentBasicBlock.outgoingEdges);
+ }
+
+ /**
+ * Ends the current basic block. This method must be used in the case where the current basic
+ * block does not have any successor.
+ *
+ * <p>WARNING: this method must be called after the currently visited instruction has been put in
+ * {@link #code} (if frames are computed, this method inserts a new Label to start a new basic
+ * block after the current instruction).
+ */
+ private void endCurrentBasicBlockWithNoSuccessor() {
+ if (compute == COMPUTE_ALL_FRAMES) {
+ Label nextBasicBlock = new Label();
+ nextBasicBlock.frame = new Frame(nextBasicBlock);
+ nextBasicBlock.resolve(code.data, code.length);
+ lastBasicBlock.nextBasicBlock = nextBasicBlock;
+ lastBasicBlock = nextBasicBlock;
+ currentBasicBlock = null;
+ } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
+ currentBasicBlock.outputStackMax = (short) maxRelativeStackSize;
+ currentBasicBlock = null;
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods: stack map frames
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Starts the visit of a new stack map frame, stored in {@link #currentFrame}.
+ *
+ * @param offset the bytecode offset of the instruction to which the frame corresponds.
+ * @param numLocal the number of local variables in the frame.
+ * @param numStack the number of stack elements in the frame.
+ * @return the index of the next element to be written in this frame.
+ */
+ int visitFrameStart(final int offset, final int numLocal, final int numStack) {
+ int frameLength = 3 + numLocal + numStack;
+ if (currentFrame == null || currentFrame.length < frameLength) {
+ currentFrame = new int[frameLength];
+ }
+ currentFrame[0] = offset;
+ currentFrame[1] = numLocal;
+ currentFrame[2] = numStack;
+ return 3;
+ }
+
+ /**
+ * Sets an abstract type in {@link #currentFrame}.
+ *
+ * @param frameIndex the index of the element to be set in {@link #currentFrame}.
+ * @param abstractType an abstract type.
+ */
+ void visitAbstractType(final int frameIndex, final int abstractType) {
+ currentFrame[frameIndex] = abstractType;
+ }
+
+ /**
+ * Ends the visit of {@link #currentFrame} by writing it in the StackMapTable entries and by
+ * updating the StackMapTable number_of_entries (except if the current frame is the first one,
+ * which is implicit in StackMapTable). Then resets {@link #currentFrame} to {@literal null}.
+ */
+ void visitFrameEnd() {
+ if (previousFrame != null) {
+ if (stackMapTableEntries == null) {
+ stackMapTableEntries = new ByteVector();
+ }
+ putFrame();
+ ++stackMapTableNumberOfEntries;
+ }
+ previousFrame = currentFrame;
+ currentFrame = null;
+ }
+
+ /** Compresses and writes {@link #currentFrame} in a new StackMapTable entry. */
+ private void putFrame() {
+ final int numLocal = currentFrame[1];
+ final int numStack = currentFrame[2];
+ if (symbolTable.getMajorVersion() < Opcodes.V1_6) {
+ // Generate a StackMap attribute entry, which are always uncompressed.
+ stackMapTableEntries.putShort(currentFrame[0]).putShort(numLocal);
+ putAbstractTypes(3, 3 + numLocal);
+ stackMapTableEntries.putShort(numStack);
+ putAbstractTypes(3 + numLocal, 3 + numLocal + numStack);
+ return;
+ }
+ final int offsetDelta =
+ stackMapTableNumberOfEntries == 0
+ ? currentFrame[0]
+ : currentFrame[0] - previousFrame[0] - 1;
+ final int previousNumlocal = previousFrame[1];
+ final int numLocalDelta = numLocal - previousNumlocal;
+ int type = Frame.FULL_FRAME;
+ if (numStack == 0) {
+ switch (numLocalDelta) {
+ case -3:
+ case -2:
+ case -1:
+ type = Frame.CHOP_FRAME;
+ break;
+ case 0:
+ type = offsetDelta < 64 ? Frame.SAME_FRAME : Frame.SAME_FRAME_EXTENDED;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ type = Frame.APPEND_FRAME;
+ break;
+ default:
+ // Keep the FULL_FRAME type.
+ break;
+ }
+ } else if (numLocalDelta == 0 && numStack == 1) {
+ type =
+ offsetDelta < 63
+ ? Frame.SAME_LOCALS_1_STACK_ITEM_FRAME
+ : Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
+ }
+ if (type != Frame.FULL_FRAME) {
+ // Verify if locals are the same as in the previous frame.
+ int frameIndex = 3;
+ for (int i = 0; i < previousNumlocal && i < numLocal; i++) {
+ if (currentFrame[frameIndex] != previousFrame[frameIndex]) {
+ type = Frame.FULL_FRAME;
+ break;
+ }
+ frameIndex++;
+ }
+ }
+ switch (type) {
+ case Frame.SAME_FRAME:
+ stackMapTableEntries.putByte(offsetDelta);
+ break;
+ case Frame.SAME_LOCALS_1_STACK_ITEM_FRAME:
+ stackMapTableEntries.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta);
+ putAbstractTypes(3 + numLocal, 4 + numLocal);
+ break;
+ case Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+ stackMapTableEntries
+ .putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
+ .putShort(offsetDelta);
+ putAbstractTypes(3 + numLocal, 4 + numLocal);
+ break;
+ case Frame.SAME_FRAME_EXTENDED:
+ stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED).putShort(offsetDelta);
+ break;
+ case Frame.CHOP_FRAME:
+ stackMapTableEntries
+ .putByte(Frame.SAME_FRAME_EXTENDED + numLocalDelta)
+ .putShort(offsetDelta);
+ break;
+ case Frame.APPEND_FRAME:
+ stackMapTableEntries
+ .putByte(Frame.SAME_FRAME_EXTENDED + numLocalDelta)
+ .putShort(offsetDelta);
+ putAbstractTypes(3 + previousNumlocal, 3 + numLocal);
+ break;
+ case Frame.FULL_FRAME:
+ default:
+ stackMapTableEntries.putByte(Frame.FULL_FRAME).putShort(offsetDelta).putShort(numLocal);
+ putAbstractTypes(3, 3 + numLocal);
+ stackMapTableEntries.putShort(numStack);
+ putAbstractTypes(3 + numLocal, 3 + numLocal + numStack);
+ break;
+ }
+ }
+
+ /**
+ * Puts some abstract types of {@link #currentFrame} in {@link #stackMapTableEntries} , using the
+ * JVMS verification_type_info format used in StackMapTable attributes.
+ *
+ * @param start index of the first type in {@link #currentFrame} to write.
+ * @param end index of last type in {@link #currentFrame} to write (exclusive).
+ */
+ private void putAbstractTypes(final int start, final int end) {
+ for (int i = start; i < end; ++i) {
+ Frame.putAbstractType(symbolTable, currentFrame[i], stackMapTableEntries);
+ }
+ }
+
+ /**
+ * Puts the given public API frame element type in {@link #stackMapTableEntries} , using the JVMS
+ * verification_type_info format used in StackMapTable attributes.
+ *
+ * @param type a frame element type described using the same format as in {@link
+ * MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
+ * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or
+ * {@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating
+ * a NEW instruction (for uninitialized types).
+ */
+ private void putFrameType(final Object type) {
+ if (type instanceof Integer) {
+ stackMapTableEntries.putByte(((Integer) type).intValue());
+ } else if (type instanceof String) {
+ stackMapTableEntries
+ .putByte(Frame.ITEM_OBJECT)
+ .putShort(symbolTable.addConstantClass((String) type).index);
+ } else {
+ stackMapTableEntries
+ .putByte(Frame.ITEM_UNINITIALIZED)
+ .putShort(((Label) type).bytecodeOffset);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns whether the attributes of this method can be copied from the attributes of the given
+ * method (assuming there is no method visitor between the given ClassReader and this
+ * MethodWriter). This method should only be called just after this MethodWriter has been created,
+ * and before any content is visited. It returns true if the attributes corresponding to the
+ * constructor arguments (at most a Signature, an Exception, a Deprecated and a Synthetic
+ * attribute) are the same as the corresponding attributes in the given method.
+ *
+ * @param source the source ClassReader from which the attributes of this method might be copied.
+ * @param hasSyntheticAttribute whether the method_info JVMS structure from which the attributes
+ * of this method might be copied contains a Synthetic attribute.
+ * @param hasDeprecatedAttribute whether the method_info JVMS structure from which the attributes
+ * of this method might be copied contains a Deprecated attribute.
+ * @param descriptorIndex the descriptor_index field of the method_info JVMS structure from which
+ * the attributes of this method might be copied.
+ * @param signatureIndex the constant pool index contained in the Signature attribute of the
+ * method_info JVMS structure from which the attributes of this method might be copied, or 0.
+ * @param exceptionsOffset the offset in 'source.b' of the Exceptions attribute of the method_info
+ * JVMS structure from which the attributes of this method might be copied, or 0.
+ * @return whether the attributes of this method can be copied from the attributes of the
+ * method_info JVMS structure in 'source.b', between 'methodInfoOffset' and 'methodInfoOffset'
+ * + 'methodInfoLength'.
+ */
+ boolean canCopyMethodAttributes(
+ final ClassReader source,
+ final boolean hasSyntheticAttribute,
+ final boolean hasDeprecatedAttribute,
+ final int descriptorIndex,
+ final int signatureIndex,
+ final int exceptionsOffset) {
+ // If the method descriptor has changed, with more locals than the max_locals field of the
+ // original Code attribute, if any, then the original method attributes can't be copied. A
+ // conservative check on the descriptor changes alone ensures this (being more precise is not
+ // worth the additional complexity, because these cases should be rare -- if a transform changes
+ // a method descriptor, most of the time it needs to change the method's code too).
+ if (source != symbolTable.getSource()
+ || descriptorIndex != this.descriptorIndex
+ || signatureIndex != this.signatureIndex
+ || hasDeprecatedAttribute != ((accessFlags & Opcodes.ACC_DEPRECATED) != 0)) {
+ return false;
+ }
+ boolean needSyntheticAttribute =
+ symbolTable.getMajorVersion() < Opcodes.V1_5 && (accessFlags & Opcodes.ACC_SYNTHETIC) != 0;
+ if (hasSyntheticAttribute != needSyntheticAttribute) {
+ return false;
+ }
+ if (exceptionsOffset == 0) {
+ if (numberOfExceptions != 0) {
+ return false;
+ }
+ } else if (source.readUnsignedShort(exceptionsOffset) == numberOfExceptions) {
+ int currentExceptionOffset = exceptionsOffset + 2;
+ for (int i = 0; i < numberOfExceptions; ++i) {
+ if (source.readUnsignedShort(currentExceptionOffset) != exceptionIndexTable[i]) {
+ return false;
+ }
+ currentExceptionOffset += 2;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the source from which the attributes of this method will be copied.
+ *
+ * @param methodInfoOffset the offset in 'symbolTable.getSource()' of the method_info JVMS
+ * structure from which the attributes of this method will be copied.
+ * @param methodInfoLength the length in 'symbolTable.getSource()' of the method_info JVMS
+ * structure from which the attributes of this method will be copied.
+ */
+ void setMethodAttributesSource(final int methodInfoOffset, final int methodInfoLength) {
+ // Don't copy the attributes yet, instead store their location in the source class reader so
+ // they can be copied later, in {@link #putMethodInfo}. Note that we skip the 6 header bytes
+ // of the method_info JVMS structure.
+ this.sourceOffset = methodInfoOffset + 6;
+ this.sourceLength = methodInfoLength - 6;
+ }
+
+ /**
+ * Returns the size of the method_info JVMS structure generated by this MethodWriter. Also add the
+ * names of the attributes of this method in the constant pool.
+ *
+ * @return the size in bytes of the method_info JVMS structure.
+ */
+ int computeMethodInfoSize() {
+ // If this method_info must be copied from an existing one, the size computation is trivial.
+ if (sourceOffset != 0) {
+ // sourceLength excludes the first 6 bytes for access_flags, name_index and descriptor_index.
+ return 6 + sourceLength;
+ }
+ // 2 bytes each for access_flags, name_index, descriptor_index and attributes_count.
+ int size = 8;
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ if (code.length > 0) {
+ if (code.length > 65535) {
+ throw new MethodTooLargeException(
+ symbolTable.getClassName(), name, descriptor, code.length);
+ }
+ symbolTable.addConstantUtf8(Constants.CODE);
+ // The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack,
+ // max_locals, code_length and attributes_count, plus the bytecode and the exception table.
+ size += 16 + code.length + Handler.getExceptionTableSize(firstHandler);
+ if (stackMapTableEntries != null) {
+ boolean useStackMapTable = symbolTable.getMajorVersion() >= Opcodes.V1_6;
+ symbolTable.addConstantUtf8(useStackMapTable ? Constants.STACK_MAP_TABLE : "StackMap");
+ // 6 header bytes and 2 bytes for number_of_entries.
+ size += 8 + stackMapTableEntries.length;
+ }
+ if (lineNumberTable != null) {
+ symbolTable.addConstantUtf8(Constants.LINE_NUMBER_TABLE);
+ // 6 header bytes and 2 bytes for line_number_table_length.
+ size += 8 + lineNumberTable.length;
+ }
+ if (localVariableTable != null) {
+ symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TABLE);
+ // 6 header bytes and 2 bytes for local_variable_table_length.
+ size += 8 + localVariableTable.length;
+ }
+ if (localVariableTypeTable != null) {
+ symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TYPE_TABLE);
+ // 6 header bytes and 2 bytes for local_variable_type_table_length.
+ size += 8 + localVariableTypeTable.length;
+ }
+ if (lastCodeRuntimeVisibleTypeAnnotation != null) {
+ size +=
+ lastCodeRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (lastCodeRuntimeInvisibleTypeAnnotation != null) {
+ size +=
+ lastCodeRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (firstCodeAttribute != null) {
+ size +=
+ firstCodeAttribute.computeAttributesSize(
+ symbolTable, code.data, code.length, maxStack, maxLocals);
+ }
+ }
+ if (numberOfExceptions > 0) {
+ symbolTable.addConstantUtf8(Constants.EXCEPTIONS);
+ size += 8 + 2 * numberOfExceptions;
+ }
+ size += Attribute.computeAttributesSize(symbolTable, accessFlags, signatureIndex);
+ size +=
+ AnnotationWriter.computeAnnotationsSize(
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation);
+ if (lastRuntimeVisibleParameterAnnotations != null) {
+ size +=
+ AnnotationWriter.computeParameterAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
+ lastRuntimeVisibleParameterAnnotations,
+ visibleAnnotableParameterCount == 0
+ ? lastRuntimeVisibleParameterAnnotations.length
+ : visibleAnnotableParameterCount);
+ }
+ if (lastRuntimeInvisibleParameterAnnotations != null) {
+ size +=
+ AnnotationWriter.computeParameterAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
+ lastRuntimeInvisibleParameterAnnotations,
+ invisibleAnnotableParameterCount == 0
+ ? lastRuntimeInvisibleParameterAnnotations.length
+ : invisibleAnnotableParameterCount);
+ }
+ if (defaultValue != null) {
+ symbolTable.addConstantUtf8(Constants.ANNOTATION_DEFAULT);
+ size += 6 + defaultValue.length;
+ }
+ if (parameters != null) {
+ symbolTable.addConstantUtf8(Constants.METHOD_PARAMETERS);
+ // 6 header bytes and 1 byte for parameters_count.
+ size += 7 + parameters.length;
+ }
+ if (firstAttribute != null) {
+ size += firstAttribute.computeAttributesSize(symbolTable);
+ }
+ return size;
+ }
+
+ /**
+ * Puts the content of the method_info JVMS structure generated by this MethodWriter into the
+ * given ByteVector.
+ *
+ * @param output where the method_info structure must be put.
+ */
+ void putMethodInfo(final ByteVector output) {
+ boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5;
+ int mask = useSyntheticAttribute ? Opcodes.ACC_SYNTHETIC : 0;
+ output.putShort(accessFlags & ~mask).putShort(nameIndex).putShort(descriptorIndex);
+ // If this method_info must be copied from an existing one, copy it now and return early.
+ if (sourceOffset != 0) {
+ output.putByteArray(symbolTable.getSource().classFileBuffer, sourceOffset, sourceLength);
+ return;
+ }
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ int attributeCount = 0;
+ if (code.length > 0) {
+ ++attributeCount;
+ }
+ if (numberOfExceptions > 0) {
+ ++attributeCount;
+ }
+ if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
+ ++attributeCount;
+ }
+ if (signatureIndex != 0) {
+ ++attributeCount;
+ }
+ if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
+ ++attributeCount;
+ }
+ if (lastRuntimeVisibleAnnotation != null) {
+ ++attributeCount;
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ ++attributeCount;
+ }
+ if (lastRuntimeVisibleParameterAnnotations != null) {
+ ++attributeCount;
+ }
+ if (lastRuntimeInvisibleParameterAnnotations != null) {
+ ++attributeCount;
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ ++attributeCount;
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ ++attributeCount;
+ }
+ if (defaultValue != null) {
+ ++attributeCount;
+ }
+ if (parameters != null) {
+ ++attributeCount;
+ }
+ if (firstAttribute != null) {
+ attributeCount += firstAttribute.getAttributeCount();
+ }
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ output.putShort(attributeCount);
+ if (code.length > 0) {
+ // 2, 2, 4 and 2 bytes respectively for max_stack, max_locals, code_length and
+ // attributes_count, plus the bytecode and the exception table.
+ int size = 10 + code.length + Handler.getExceptionTableSize(firstHandler);
+ int codeAttributeCount = 0;
+ if (stackMapTableEntries != null) {
+ // 6 header bytes and 2 bytes for number_of_entries.
+ size += 8 + stackMapTableEntries.length;
+ ++codeAttributeCount;
+ }
+ if (lineNumberTable != null) {
+ // 6 header bytes and 2 bytes for line_number_table_length.
+ size += 8 + lineNumberTable.length;
+ ++codeAttributeCount;
+ }
+ if (localVariableTable != null) {
+ // 6 header bytes and 2 bytes for local_variable_table_length.
+ size += 8 + localVariableTable.length;
+ ++codeAttributeCount;
+ }
+ if (localVariableTypeTable != null) {
+ // 6 header bytes and 2 bytes for local_variable_type_table_length.
+ size += 8 + localVariableTypeTable.length;
+ ++codeAttributeCount;
+ }
+ if (lastCodeRuntimeVisibleTypeAnnotation != null) {
+ size +=
+ lastCodeRuntimeVisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ ++codeAttributeCount;
+ }
+ if (lastCodeRuntimeInvisibleTypeAnnotation != null) {
+ size +=
+ lastCodeRuntimeInvisibleTypeAnnotation.computeAnnotationsSize(
+ Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+ ++codeAttributeCount;
+ }
+ if (firstCodeAttribute != null) {
+ size +=
+ firstCodeAttribute.computeAttributesSize(
+ symbolTable, code.data, code.length, maxStack, maxLocals);
+ codeAttributeCount += firstCodeAttribute.getAttributeCount();
+ }
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.CODE))
+ .putInt(size)
+ .putShort(maxStack)
+ .putShort(maxLocals)
+ .putInt(code.length)
+ .putByteArray(code.data, 0, code.length);
+ Handler.putExceptionTable(firstHandler, output);
+ output.putShort(codeAttributeCount);
+ if (stackMapTableEntries != null) {
+ boolean useStackMapTable = symbolTable.getMajorVersion() >= Opcodes.V1_6;
+ output
+ .putShort(
+ symbolTable.addConstantUtf8(
+ useStackMapTable ? Constants.STACK_MAP_TABLE : "StackMap"))
+ .putInt(2 + stackMapTableEntries.length)
+ .putShort(stackMapTableNumberOfEntries)
+ .putByteArray(stackMapTableEntries.data, 0, stackMapTableEntries.length);
+ }
+ if (lineNumberTable != null) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.LINE_NUMBER_TABLE))
+ .putInt(2 + lineNumberTable.length)
+ .putShort(lineNumberTableLength)
+ .putByteArray(lineNumberTable.data, 0, lineNumberTable.length);
+ }
+ if (localVariableTable != null) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TABLE))
+ .putInt(2 + localVariableTable.length)
+ .putShort(localVariableTableLength)
+ .putByteArray(localVariableTable.data, 0, localVariableTable.length);
+ }
+ if (localVariableTypeTable != null) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TYPE_TABLE))
+ .putInt(2 + localVariableTypeTable.length)
+ .putShort(localVariableTypeTableLength)
+ .putByteArray(localVariableTypeTable.data, 0, localVariableTypeTable.length);
+ }
+ if (lastCodeRuntimeVisibleTypeAnnotation != null) {
+ lastCodeRuntimeVisibleTypeAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS), output);
+ }
+ if (lastCodeRuntimeInvisibleTypeAnnotation != null) {
+ lastCodeRuntimeInvisibleTypeAnnotation.putAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS), output);
+ }
+ if (firstCodeAttribute != null) {
+ firstCodeAttribute.putAttributes(
+ symbolTable, code.data, code.length, maxStack, maxLocals, output);
+ }
+ }
+ if (numberOfExceptions > 0) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.EXCEPTIONS))
+ .putInt(2 + 2 * numberOfExceptions)
+ .putShort(numberOfExceptions);
+ for (int exceptionIndex : exceptionIndexTable) {
+ output.putShort(exceptionIndex);
+ }
+ }
+ Attribute.putAttributes(symbolTable, accessFlags, signatureIndex, output);
+ AnnotationWriter.putAnnotations(
+ symbolTable,
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation,
+ output);
+ if (lastRuntimeVisibleParameterAnnotations != null) {
+ AnnotationWriter.putParameterAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS),
+ lastRuntimeVisibleParameterAnnotations,
+ visibleAnnotableParameterCount == 0
+ ? lastRuntimeVisibleParameterAnnotations.length
+ : visibleAnnotableParameterCount,
+ output);
+ }
+ if (lastRuntimeInvisibleParameterAnnotations != null) {
+ AnnotationWriter.putParameterAnnotations(
+ symbolTable.addConstantUtf8(Constants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS),
+ lastRuntimeInvisibleParameterAnnotations,
+ invisibleAnnotableParameterCount == 0
+ ? lastRuntimeInvisibleParameterAnnotations.length
+ : invisibleAnnotableParameterCount,
+ output);
+ }
+ if (defaultValue != null) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.ANNOTATION_DEFAULT))
+ .putInt(defaultValue.length)
+ .putByteArray(defaultValue.data, 0, defaultValue.length);
+ }
+ if (parameters != null) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.METHOD_PARAMETERS))
+ .putInt(1 + parameters.length)
+ .putByte(parametersCount)
+ .putByteArray(parameters.data, 0, parameters.length);
+ }
+ if (firstAttribute != null) {
+ firstAttribute.putAttributes(symbolTable, output);
+ }
+ }
+
+ /**
+ * Collects the attributes of this method into the given set of attribute prototypes.
+ *
+ * @param attributePrototypes a set of attribute prototypes.
+ */
+ final void collectAttributePrototypes(final Attribute.Set attributePrototypes) {
+ attributePrototypes.addAttributes(firstAttribute);
+ attributePrototypes.addAttributes(firstCodeAttribute);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java b/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java
new file mode 100644
index 00000000..9a566f3d
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java
@@ -0,0 +1,196 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in the following
+ * order: ( {@code visitMainClass} | ( {@code visitPackage} | {@code visitRequire} | {@code
+ * visitExport} | {@code visitOpen} | {@code visitUse} | {@code visitProvide} )* ) {@code visitEnd}.
+ *
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+public abstract class ModuleVisitor {
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of {@link
+ * Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ */
+ protected final int api;
+
+ /**
+ * The module visitor to which this visitor must delegate method calls. May be {@literal null}.
+ */
+ protected ModuleVisitor mv;
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
+ * or {@link Opcodes#ASM7}.
+ */
+ protected ModuleVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link ModuleVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
+ * or {@link Opcodes#ASM7}.
+ * @param moduleVisitor the module visitor to which this visitor must delegate method calls. May
+ * be null.
+ */
+ protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.mv = moduleVisitor;
+ }
+
+ /**
+ * The module visitor to which this visitor must delegate method calls. May be {@literal null}.
+ *
+ * @return the module visitor to which this visitor must delegate method calls, or {@literal
+ * null}.
+ */
+ public ModuleVisitor getDelegate() {
+ return mv;
+ }
+
+ /**
+ * Visit the main class of the current module.
+ *
+ * @param mainClass the internal name of the main class of the current module (see {@link
+ * Type#getInternalName()}).
+ */
+ public void visitMainClass(final String mainClass) {
+ if (mv != null) {
+ mv.visitMainClass(mainClass);
+ }
+ }
+
+ /**
+ * Visit a package of the current module.
+ *
+ * @param packaze the internal name of a package (see {@link Type#getInternalName()}).
+ */
+ public void visitPackage(final String packaze) {
+ if (mv != null) {
+ mv.visitPackage(packaze);
+ }
+ }
+
+ /**
+ * Visits a dependence of the current module.
+ *
+ * @param module the fully qualified name (using dots) of the dependence.
+ * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
+ * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param version the module version at compile time, or {@literal null}.
+ */
+ public void visitRequire(final String module, final int access, final String version) {
+ if (mv != null) {
+ mv.visitRequire(module, access, version);
+ }
+ }
+
+ /**
+ * Visit an exported package of the current module.
+ *
+ * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}).
+ * @param access the access flag of the exported package, valid values are among {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param modules the fully qualified names (using dots) of the modules that can access the public
+ * classes of the exported package, or {@literal null}.
+ */
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ if (mv != null) {
+ mv.visitExport(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit an open package of the current module.
+ *
+ * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}).
+ * @param access the access flag of the opened package, valid values are among {@code
+ * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+ * @param modules the fully qualified names (using dots) of the modules that can use deep
+ * reflection to the classes of the open package, or {@literal null}.
+ */
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ if (mv != null) {
+ mv.visitOpen(packaze, access, modules);
+ }
+ }
+
+ /**
+ * Visit a service used by the current module. The name must be the internal name of an interface
+ * or a class.
+ *
+ * @param service the internal name of the service (see {@link Type#getInternalName()}).
+ */
+ public void visitUse(final String service) {
+ if (mv != null) {
+ mv.visitUse(service);
+ }
+ }
+
+ /**
+ * Visit an implementation of a service.
+ *
+ * @param service the internal name of the service (see {@link Type#getInternalName()}).
+ * @param providers the internal names (see {@link Type#getInternalName()}) of the implementations
+ * of the service (there is at least one provider).
+ */
+ public void visitProvide(final String service, final String... providers) {
+ if (mv != null) {
+ mv.visitProvide(service, providers);
+ }
+ }
+
+ /**
+ * Visits the end of the module. This method, which is the last one to be called, is used to
+ * inform the visitor that everything have been visited.
+ */
+ public void visitEnd() {
+ if (mv != null) {
+ mv.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/ModuleWriter.java b/asm/src/main/java/org/objectweb/asm/ModuleWriter.java
new file mode 100644
index 00000000..0ace0fa7
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/ModuleWriter.java
@@ -0,0 +1,253 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A {@link ModuleVisitor} that generates the corresponding Module, ModulePackages and
+ * ModuleMainClass attributes, as defined in the Java Virtual Machine Specification (JVMS).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.25">JVMS
+ * 4.7.25</a>
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.26">JVMS
+ * 4.7.26</a>
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.27">JVMS
+ * 4.7.27</a>
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+final class ModuleWriter extends ModuleVisitor {
+
+ /** Where the constants used in this AnnotationWriter must be stored. */
+ private final SymbolTable symbolTable;
+
+ /** The module_name_index field of the JVMS Module attribute. */
+ private final int moduleNameIndex;
+
+ /** The module_flags field of the JVMS Module attribute. */
+ private final int moduleFlags;
+
+ /** The module_version_index field of the JVMS Module attribute. */
+ private final int moduleVersionIndex;
+
+ /** The requires_count field of the JVMS Module attribute. */
+ private int requiresCount;
+
+ /** The binary content of the 'requires' array of the JVMS Module attribute. */
+ private final ByteVector requires;
+
+ /** The exports_count field of the JVMS Module attribute. */
+ private int exportsCount;
+
+ /** The binary content of the 'exports' array of the JVMS Module attribute. */
+ private final ByteVector exports;
+
+ /** The opens_count field of the JVMS Module attribute. */
+ private int opensCount;
+
+ /** The binary content of the 'opens' array of the JVMS Module attribute. */
+ private final ByteVector opens;
+
+ /** The uses_count field of the JVMS Module attribute. */
+ private int usesCount;
+
+ /** The binary content of the 'uses_index' array of the JVMS Module attribute. */
+ private final ByteVector usesIndex;
+
+ /** The provides_count field of the JVMS Module attribute. */
+ private int providesCount;
+
+ /** The binary content of the 'provides' array of the JVMS Module attribute. */
+ private final ByteVector provides;
+
+ /** The provides_count field of the JVMS ModulePackages attribute. */
+ private int packageCount;
+
+ /** The binary content of the 'package_index' array of the JVMS ModulePackages attribute. */
+ private final ByteVector packageIndex;
+
+ /** The main_class_index field of the JVMS ModuleMainClass attribute, or 0. */
+ private int mainClassIndex;
+
+ ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.symbolTable = symbolTable;
+ this.moduleNameIndex = name;
+ this.moduleFlags = access;
+ this.moduleVersionIndex = version;
+ this.requires = new ByteVector();
+ this.exports = new ByteVector();
+ this.opens = new ByteVector();
+ this.usesIndex = new ByteVector();
+ this.provides = new ByteVector();
+ this.packageIndex = new ByteVector();
+ }
+
+ @Override
+ public void visitMainClass(final String mainClass) {
+ this.mainClassIndex = symbolTable.addConstantClass(mainClass).index;
+ }
+
+ @Override
+ public void visitPackage(final String packaze) {
+ packageIndex.putShort(symbolTable.addConstantPackage(packaze).index);
+ packageCount++;
+ }
+
+ @Override
+ public void visitRequire(final String module, final int access, final String version) {
+ requires
+ .putShort(symbolTable.addConstantModule(module).index)
+ .putShort(access)
+ .putShort(version == null ? 0 : symbolTable.addConstantUtf8(version));
+ requiresCount++;
+ }
+
+ @Override
+ public void visitExport(final String packaze, final int access, final String... modules) {
+ exports.putShort(symbolTable.addConstantPackage(packaze).index).putShort(access);
+ if (modules == null) {
+ exports.putShort(0);
+ } else {
+ exports.putShort(modules.length);
+ for (String module : modules) {
+ exports.putShort(symbolTable.addConstantModule(module).index);
+ }
+ }
+ exportsCount++;
+ }
+
+ @Override
+ public void visitOpen(final String packaze, final int access, final String... modules) {
+ opens.putShort(symbolTable.addConstantPackage(packaze).index).putShort(access);
+ if (modules == null) {
+ opens.putShort(0);
+ } else {
+ opens.putShort(modules.length);
+ for (String module : modules) {
+ opens.putShort(symbolTable.addConstantModule(module).index);
+ }
+ }
+ opensCount++;
+ }
+
+ @Override
+ public void visitUse(final String service) {
+ usesIndex.putShort(symbolTable.addConstantClass(service).index);
+ usesCount++;
+ }
+
+ @Override
+ public void visitProvide(final String service, final String... providers) {
+ provides.putShort(symbolTable.addConstantClass(service).index);
+ provides.putShort(providers.length);
+ for (String provider : providers) {
+ provides.putShort(symbolTable.addConstantClass(provider).index);
+ }
+ providesCount++;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ /**
+ * Returns the number of Module, ModulePackages and ModuleMainClass attributes generated by this
+ * ModuleWriter.
+ *
+ * @return the number of Module, ModulePackages and ModuleMainClass attributes (between 1 and 3).
+ */
+ int getAttributeCount() {
+ return 1 + (packageCount > 0 ? 1 : 0) + (mainClassIndex > 0 ? 1 : 0);
+ }
+
+ /**
+ * Returns the size of the Module, ModulePackages and ModuleMainClass attributes generated by this
+ * ModuleWriter. Also add the names of these attributes in the constant pool.
+ *
+ * @return the size in bytes of the Module, ModulePackages and ModuleMainClass attributes.
+ */
+ int computeAttributesSize() {
+ symbolTable.addConstantUtf8(Constants.MODULE);
+ // 6 attribute header bytes, 6 bytes for name, flags and version, and 5 * 2 bytes for counts.
+ int size =
+ 22 + requires.length + exports.length + opens.length + usesIndex.length + provides.length;
+ if (packageCount > 0) {
+ symbolTable.addConstantUtf8(Constants.MODULE_PACKAGES);
+ // 6 attribute header bytes, and 2 bytes for package_count.
+ size += 8 + packageIndex.length;
+ }
+ if (mainClassIndex > 0) {
+ symbolTable.addConstantUtf8(Constants.MODULE_MAIN_CLASS);
+ // 6 attribute header bytes, and 2 bytes for main_class_index.
+ size += 8;
+ }
+ return size;
+ }
+
+ /**
+ * Puts the Module, ModulePackages and ModuleMainClass attributes generated by this ModuleWriter
+ * in the given ByteVector.
+ *
+ * @param output where the attributes must be put.
+ */
+ void putAttributes(final ByteVector output) {
+ // 6 bytes for name, flags and version, and 5 * 2 bytes for counts.
+ int moduleAttributeLength =
+ 16 + requires.length + exports.length + opens.length + usesIndex.length + provides.length;
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.MODULE))
+ .putInt(moduleAttributeLength)
+ .putShort(moduleNameIndex)
+ .putShort(moduleFlags)
+ .putShort(moduleVersionIndex)
+ .putShort(requiresCount)
+ .putByteArray(requires.data, 0, requires.length)
+ .putShort(exportsCount)
+ .putByteArray(exports.data, 0, exports.length)
+ .putShort(opensCount)
+ .putByteArray(opens.data, 0, opens.length)
+ .putShort(usesCount)
+ .putByteArray(usesIndex.data, 0, usesIndex.length)
+ .putShort(providesCount)
+ .putByteArray(provides.data, 0, provides.length);
+ if (packageCount > 0) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.MODULE_PACKAGES))
+ .putInt(2 + packageIndex.length)
+ .putShort(packageCount)
+ .putByteArray(packageIndex.data, 0, packageIndex.length);
+ }
+ if (mainClassIndex > 0) {
+ output
+ .putShort(symbolTable.addConstantUtf8(Constants.MODULE_MAIN_CLASS))
+ .putInt(2)
+ .putShort(mainClassIndex);
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Opcodes.java b/asm/src/main/java/org/objectweb/asm/Opcodes.java
new file mode 100644
index 00000000..4a85a445
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Opcodes.java
@@ -0,0 +1,563 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * The JVM opcodes, access flags and array type codes. This interface does not define all the JVM
+ * opcodes because some opcodes are automatically handled. For example, the xLOAD and xSTORE opcodes
+ * are automatically replaced by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and
+ * xSTORE_n opcodes are therefore not defined in this interface. Likewise for LDC, automatically
+ * replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html">JVMS 6</a>
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+// DontCheck(InterfaceIsType): can't be fixed (for backward binary compatibility).
+public interface Opcodes {
+
+ // ASM API versions.
+
+ int ASM4 = 4 << 16 | 0 << 8;
+ int ASM5 = 5 << 16 | 0 << 8;
+ int ASM6 = 6 << 16 | 0 << 8;
+ int ASM7 = 7 << 16 | 0 << 8;
+ int ASM8 = 8 << 16 | 0 << 8;
+ int ASM9 = 9 << 16 | 0 << 8;
+
+ /**
+ * <i>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
+ * will break existing code using it. Only code compiled with --enable-preview can use this.</i>
+ *
+ * @deprecated This API is experimental.
+ */
+ @Deprecated int ASM10_EXPERIMENTAL = 1 << 24 | 10 << 16 | 0 << 8;
+
+ /*
+ * Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff
+ * method in API_OLD is deprecated and replaced with visitNewStuff in API_NEW, then the
+ * redirection should be done as follows:
+ *
+ * <pre>
+ * public class StuffVisitor {
+ * ...
+ *
+ * &#64;Deprecated public void visitOldStuff(int arg, ...) {
+ * // SOURCE_DEPRECATED means "a call from a deprecated method using the old 'api' value".
+ * visitNewStuf(arg | (api &#60; API_NEW ? SOURCE_DEPRECATED : 0), ...);
+ * }
+ *
+ * public void visitNewStuff(int argAndSource, ...) {
+ * if (api &#60; API_NEW &#38;&#38; (argAndSource &#38; SOURCE_DEPRECATED) == 0) {
+ * visitOldStuff(argAndSource, ...);
+ * } else {
+ * int arg = argAndSource &#38; ~SOURCE_MASK;
+ * [ do stuff ]
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>If 'api' is equal to API_NEW, there are two cases:
+ *
+ * <ul>
+ * <li>call visitNewStuff: the redirection test is skipped and 'do stuff' is executed directly.
+ * <li>call visitOldSuff: the source is not set to SOURCE_DEPRECATED before calling
+ * visitNewStuff, but the redirection test is skipped anyway in visitNewStuff, which
+ * directly executes 'do stuff'.
+ * </ul>
+ *
+ * <p>If 'api' is equal to API_OLD, there are two cases:
+ *
+ * <ul>
+ * <li>call visitOldSuff: the source is set to SOURCE_DEPRECATED before calling visitNewStuff.
+ * Because of this visitNewStuff does not redirect back to visitOldStuff, and instead
+ * executes 'do stuff'.
+ * <li>call visitNewStuff: the call is redirected to visitOldStuff because the source is 0.
+ * visitOldStuff now sets the source to SOURCE_DEPRECATED and calls visitNewStuff back. This
+ * time visitNewStuff does not redirect the call, and instead executes 'do stuff'.
+ * </ul>
+ *
+ * <h1>User subclasses</h1>
+ *
+ * <p>If a user subclass overrides one of these methods, there are only two cases: either 'api' is
+ * API_OLD and visitOldStuff is overridden (and visitNewStuff is not), or 'api' is API_NEW or
+ * more, and visitNewStuff is overridden (and visitOldStuff is not). Any other case is a user
+ * programming error.
+ *
+ * <p>If 'api' is equal to API_NEW, the class hierarchy is equivalent to
+ *
+ * <pre>
+ * public class StuffVisitor {
+ * &#64;Deprecated public void visitOldStuff(int arg, ...) { visitNewStuf(arg, ...); }
+ * public void visitNewStuff(int arg, ...) { [ do stuff ] }
+ * }
+ * class UserStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitNewStuff(int arg, ...) {
+ * super.visitNewStuff(int arg, ...); // optional
+ * [ do user stuff ]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>It is then obvious that whether visitNewStuff or visitOldStuff is called, 'do stuff' and 'do
+ * user stuff' will be executed, in this order.
+ *
+ * <p>If 'api' is equal to API_OLD, the class hierarchy is equivalent to
+ *
+ * <pre>
+ * public class StuffVisitor {
+ * &#64;Deprecated public void visitOldStuff(int arg, ...) {
+ * visitNewStuff(arg | SOURCE_DEPRECATED, ...);
+ * }
+ * public void visitNewStuff(int argAndSource...) {
+ * if ((argAndSource & SOURCE_DEPRECATED) == 0) {
+ * visitOldStuff(argAndSource, ...);
+ * } else {
+ * int arg = argAndSource &#38; ~SOURCE_MASK;
+ * [ do stuff ]
+ * }
+ * }
+ * }
+ * class UserStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitOldStuff(int arg, ...) {
+ * super.visitOldStuff(int arg, ...); // optional
+ * [ do user stuff ]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>and there are two cases:
+ *
+ * <ul>
+ * <li>call visitOldStuff: in the call to super.visitOldStuff, the source is set to
+ * SOURCE_DEPRECATED and visitNewStuff is called. Here 'do stuff' is run because the source
+ * was previously set to SOURCE_DEPRECATED, and execution eventually returns to
+ * UserStuffVisitor.visitOldStuff, where 'do user stuff' is run.
+ * <li>call visitNewStuff: the call is redirected to UserStuffVisitor.visitOldStuff because the
+ * source is 0. Execution continues as in the previous case, resulting in 'do stuff' and 'do
+ * user stuff' being executed, in this order.
+ * </ul>
+ *
+ * <h1>ASM subclasses</h1>
+ *
+ * <p>In ASM packages, subclasses of StuffVisitor can typically be sub classed again by the user,
+ * and can be used with API_OLD or API_NEW. Because of this, if such a subclass must override
+ * visitNewStuff, it must do so in the following way (and must not override visitOldStuff):
+ *
+ * <pre>
+ * public class AsmStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitNewStuff(int argAndSource, ...) {
+ * if (api &#60; API_NEW &#38;&#38; (argAndSource &#38; SOURCE_DEPRECATED) == 0) {
+ * super.visitNewStuff(argAndSource, ...);
+ * return;
+ * }
+ * super.visitNewStuff(argAndSource, ...); // optional
+ * int arg = argAndSource &#38; ~SOURCE_MASK;
+ * [ do other stuff ]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>If a user class extends this with 'api' equal to API_NEW, the class hierarchy is equivalent
+ * to
+ *
+ * <pre>
+ * public class StuffVisitor {
+ * &#64;Deprecated public void visitOldStuff(int arg, ...) { visitNewStuf(arg, ...); }
+ * public void visitNewStuff(int arg, ...) { [ do stuff ] }
+ * }
+ * public class AsmStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitNewStuff(int arg, ...) {
+ * super.visitNewStuff(arg, ...);
+ * [ do other stuff ]
+ * }
+ * }
+ * class UserStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitNewStuff(int arg, ...) {
+ * super.visitNewStuff(int arg, ...);
+ * [ do user stuff ]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>It is then obvious that whether visitNewStuff or visitOldStuff is called, 'do stuff', 'do
+ * other stuff' and 'do user stuff' will be executed, in this order. If, on the other hand, a user
+ * class extends AsmStuffVisitor with 'api' equal to API_OLD, the class hierarchy is equivalent to
+ *
+ * <pre>
+ * public class StuffVisitor {
+ * &#64;Deprecated public void visitOldStuff(int arg, ...) {
+ * visitNewStuf(arg | SOURCE_DEPRECATED, ...);
+ * }
+ * public void visitNewStuff(int argAndSource, ...) {
+ * if ((argAndSource & SOURCE_DEPRECATED) == 0) {
+ * visitOldStuff(argAndSource, ...);
+ * } else {
+ * int arg = argAndSource &#38; ~SOURCE_MASK;
+ * [ do stuff ]
+ * }
+ * }
+ * }
+ * public class AsmStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitNewStuff(int argAndSource, ...) {
+ * if ((argAndSource &#38; SOURCE_DEPRECATED) == 0) {
+ * super.visitNewStuff(argAndSource, ...);
+ * return;
+ * }
+ * super.visitNewStuff(argAndSource, ...); // optional
+ * int arg = argAndSource &#38; ~SOURCE_MASK;
+ * [ do other stuff ]
+ * }
+ * }
+ * class UserStuffVisitor extends StuffVisitor {
+ * &#64;Override public void visitOldStuff(int arg, ...) {
+ * super.visitOldStuff(arg, ...);
+ * [ do user stuff ]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>and, here again, whether visitNewStuff or visitOldStuff is called, 'do stuff', 'do other
+ * stuff' and 'do user stuff' will be executed, in this order (exercise left to the reader).
+ *
+ * <h1>Notes</h1>
+ *
+ * <ul>
+ * <li>the SOURCE_DEPRECATED flag is set only if 'api' is API_OLD, just before calling
+ * visitNewStuff. By hypothesis, this method is not overridden by the user. Therefore, user
+ * classes can never see this flag. Only ASM subclasses must take care of extracting the
+ * actual argument value by clearing the source flags.
+ * <li>because the SOURCE_DEPRECATED flag is immediately cleared in the caller, the caller can
+ * call visitOldStuff or visitNewStuff (in 'do stuff' and 'do user stuff') on a delegate
+ * visitor without any risks (breaking the redirection logic, "leaking" the flag, etc).
+ * <li>all the scenarios discussed above are unit tested in MethodVisitorTest.
+ * </ul>
+ */
+
+ int SOURCE_DEPRECATED = 0x100;
+ int SOURCE_MASK = SOURCE_DEPRECATED;
+
+ // Java ClassFile versions (the minor version is stored in the 16 most significant bits, and the
+ // major version in the 16 least significant bits).
+
+ int V1_1 = 3 << 16 | 45;
+ int V1_2 = 0 << 16 | 46;
+ int V1_3 = 0 << 16 | 47;
+ int V1_4 = 0 << 16 | 48;
+ int V1_5 = 0 << 16 | 49;
+ int V1_6 = 0 << 16 | 50;
+ int V1_7 = 0 << 16 | 51;
+ int V1_8 = 0 << 16 | 52;
+ int V9 = 0 << 16 | 53;
+ int V10 = 0 << 16 | 54;
+ int V11 = 0 << 16 | 55;
+ int V12 = 0 << 16 | 56;
+ int V13 = 0 << 16 | 57;
+ int V14 = 0 << 16 | 58;
+ int V15 = 0 << 16 | 59;
+ int V16 = 0 << 16 | 60;
+ int V17 = 0 << 16 | 61;
+ int V18 = 0 << 16 | 62;
+ int V19 = 0 << 16 | 63;
+ int V20 = 0 << 16 | 64;
+
+ /**
+ * Version flag indicating that the class is using 'preview' features.
+ *
+ * <p>{@code version & V_PREVIEW == V_PREVIEW} tests if a version is flagged with {@code
+ * V_PREVIEW}.
+ */
+ int V_PREVIEW = 0xFFFF0000;
+
+ // Access flags values, defined in
+ // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1
+ // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5-200-A.1
+ // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6-200-A.1
+ // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.25
+
+ int ACC_PUBLIC = 0x0001; // class, field, method
+ int ACC_PRIVATE = 0x0002; // class, field, method
+ int ACC_PROTECTED = 0x0004; // class, field, method
+ int ACC_STATIC = 0x0008; // field, method
+ int ACC_FINAL = 0x0010; // class, field, method, parameter
+ int ACC_SUPER = 0x0020; // class
+ int ACC_SYNCHRONIZED = 0x0020; // method
+ int ACC_OPEN = 0x0020; // module
+ int ACC_TRANSITIVE = 0x0020; // module requires
+ int ACC_VOLATILE = 0x0040; // field
+ int ACC_BRIDGE = 0x0040; // method
+ int ACC_STATIC_PHASE = 0x0040; // module requires
+ int ACC_VARARGS = 0x0080; // method
+ int ACC_TRANSIENT = 0x0080; // field
+ int ACC_NATIVE = 0x0100; // method
+ int ACC_INTERFACE = 0x0200; // class
+ int ACC_ABSTRACT = 0x0400; // class, method
+ int ACC_STRICT = 0x0800; // method
+ int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
+ int ACC_ANNOTATION = 0x2000; // class
+ int ACC_ENUM = 0x4000; // class(?) field inner
+ int ACC_MANDATED = 0x8000; // field, method, parameter, module, module *
+ int ACC_MODULE = 0x8000; // class
+
+ // ASM specific access flags.
+ // WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard
+ // access flags, and also to make sure that these flags are automatically filtered out when
+ // written in class files (because access flags are stored using 16 bits only).
+
+ int ACC_RECORD = 0x10000; // class
+ int ACC_DEPRECATED = 0x20000; // class, field, method
+
+ // Possible values for the type operand of the NEWARRAY instruction.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html#jvms-6.5.newarray.
+
+ int T_BOOLEAN = 4;
+ int T_CHAR = 5;
+ int T_FLOAT = 6;
+ int T_DOUBLE = 7;
+ int T_BYTE = 8;
+ int T_SHORT = 9;
+ int T_INT = 10;
+ int T_LONG = 11;
+
+ // Possible values for the reference_kind field of CONSTANT_MethodHandle_info structures.
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8.
+
+ int H_GETFIELD = 1;
+ int H_GETSTATIC = 2;
+ int H_PUTFIELD = 3;
+ int H_PUTSTATIC = 4;
+ int H_INVOKEVIRTUAL = 5;
+ int H_INVOKESTATIC = 6;
+ int H_INVOKESPECIAL = 7;
+ int H_NEWINVOKESPECIAL = 8;
+ int H_INVOKEINTERFACE = 9;
+
+ // ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}.
+
+ /** An expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */
+ int F_NEW = -1;
+
+ /** A compressed frame with complete frame data. */
+ int F_FULL = 0;
+
+ /**
+ * A compressed frame where locals are the same as the locals in the previous frame, except that
+ * additional 1-3 locals are defined, and with an empty stack.
+ */
+ int F_APPEND = 1;
+
+ /**
+ * A compressed frame where locals are the same as the locals in the previous frame, except that
+ * the last 1-3 locals are absent and with an empty stack.
+ */
+ int F_CHOP = 2;
+
+ /**
+ * A compressed frame with exactly the same locals as the previous frame and with an empty stack.
+ */
+ int F_SAME = 3;
+
+ /**
+ * A compressed frame with exactly the same locals as the previous frame and with a single value
+ * on the stack.
+ */
+ int F_SAME1 = 4;
+
+ // Standard stack map frame element types, used in {@link ClassVisitor#visitFrame}.
+
+ Integer TOP = Frame.ITEM_TOP;
+ Integer INTEGER = Frame.ITEM_INTEGER;
+ Integer FLOAT = Frame.ITEM_FLOAT;
+ Integer DOUBLE = Frame.ITEM_DOUBLE;
+ Integer LONG = Frame.ITEM_LONG;
+ Integer NULL = Frame.ITEM_NULL;
+ Integer UNINITIALIZED_THIS = Frame.ITEM_UNINITIALIZED_THIS;
+
+ // The JVM opcode values (with the MethodVisitor method name used to visit them in comment, and
+ // where '-' means 'same method name as on the previous line').
+ // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html.
+
+ int NOP = 0; // visitInsn
+ int ACONST_NULL = 1; // -
+ int ICONST_M1 = 2; // -
+ int ICONST_0 = 3; // -
+ int ICONST_1 = 4; // -
+ int ICONST_2 = 5; // -
+ int ICONST_3 = 6; // -
+ int ICONST_4 = 7; // -
+ int ICONST_5 = 8; // -
+ int LCONST_0 = 9; // -
+ int LCONST_1 = 10; // -
+ int FCONST_0 = 11; // -
+ int FCONST_1 = 12; // -
+ int FCONST_2 = 13; // -
+ int DCONST_0 = 14; // -
+ int DCONST_1 = 15; // -
+ int BIPUSH = 16; // visitIntInsn
+ int SIPUSH = 17; // -
+ int LDC = 18; // visitLdcInsn
+ int ILOAD = 21; // visitVarInsn
+ int LLOAD = 22; // -
+ int FLOAD = 23; // -
+ int DLOAD = 24; // -
+ int ALOAD = 25; // -
+ int IALOAD = 46; // visitInsn
+ int LALOAD = 47; // -
+ int FALOAD = 48; // -
+ int DALOAD = 49; // -
+ int AALOAD = 50; // -
+ int BALOAD = 51; // -
+ int CALOAD = 52; // -
+ int SALOAD = 53; // -
+ int ISTORE = 54; // visitVarInsn
+ int LSTORE = 55; // -
+ int FSTORE = 56; // -
+ int DSTORE = 57; // -
+ int ASTORE = 58; // -
+ int IASTORE = 79; // visitInsn
+ int LASTORE = 80; // -
+ int FASTORE = 81; // -
+ int DASTORE = 82; // -
+ int AASTORE = 83; // -
+ int BASTORE = 84; // -
+ int CASTORE = 85; // -
+ int SASTORE = 86; // -
+ int POP = 87; // -
+ int POP2 = 88; // -
+ int DUP = 89; // -
+ int DUP_X1 = 90; // -
+ int DUP_X2 = 91; // -
+ int DUP2 = 92; // -
+ int DUP2_X1 = 93; // -
+ int DUP2_X2 = 94; // -
+ int SWAP = 95; // -
+ int IADD = 96; // -
+ int LADD = 97; // -
+ int FADD = 98; // -
+ int DADD = 99; // -
+ int ISUB = 100; // -
+ int LSUB = 101; // -
+ int FSUB = 102; // -
+ int DSUB = 103; // -
+ int IMUL = 104; // -
+ int LMUL = 105; // -
+ int FMUL = 106; // -
+ int DMUL = 107; // -
+ int IDIV = 108; // -
+ int LDIV = 109; // -
+ int FDIV = 110; // -
+ int DDIV = 111; // -
+ int IREM = 112; // -
+ int LREM = 113; // -
+ int FREM = 114; // -
+ int DREM = 115; // -
+ int INEG = 116; // -
+ int LNEG = 117; // -
+ int FNEG = 118; // -
+ int DNEG = 119; // -
+ int ISHL = 120; // -
+ int LSHL = 121; // -
+ int ISHR = 122; // -
+ int LSHR = 123; // -
+ int IUSHR = 124; // -
+ int LUSHR = 125; // -
+ int IAND = 126; // -
+ int LAND = 127; // -
+ int IOR = 128; // -
+ int LOR = 129; // -
+ int IXOR = 130; // -
+ int LXOR = 131; // -
+ int IINC = 132; // visitIincInsn
+ int I2L = 133; // visitInsn
+ int I2F = 134; // -
+ int I2D = 135; // -
+ int L2I = 136; // -
+ int L2F = 137; // -
+ int L2D = 138; // -
+ int F2I = 139; // -
+ int F2L = 140; // -
+ int F2D = 141; // -
+ int D2I = 142; // -
+ int D2L = 143; // -
+ int D2F = 144; // -
+ int I2B = 145; // -
+ int I2C = 146; // -
+ int I2S = 147; // -
+ int LCMP = 148; // -
+ int FCMPL = 149; // -
+ int FCMPG = 150; // -
+ int DCMPL = 151; // -
+ int DCMPG = 152; // -
+ int IFEQ = 153; // visitJumpInsn
+ int IFNE = 154; // -
+ int IFLT = 155; // -
+ int IFGE = 156; // -
+ int IFGT = 157; // -
+ int IFLE = 158; // -
+ int IF_ICMPEQ = 159; // -
+ int IF_ICMPNE = 160; // -
+ int IF_ICMPLT = 161; // -
+ int IF_ICMPGE = 162; // -
+ int IF_ICMPGT = 163; // -
+ int IF_ICMPLE = 164; // -
+ int IF_ACMPEQ = 165; // -
+ int IF_ACMPNE = 166; // -
+ int GOTO = 167; // -
+ int JSR = 168; // -
+ int RET = 169; // visitVarInsn
+ int TABLESWITCH = 170; // visiTableSwitchInsn
+ int LOOKUPSWITCH = 171; // visitLookupSwitch
+ int IRETURN = 172; // visitInsn
+ int LRETURN = 173; // -
+ int FRETURN = 174; // -
+ int DRETURN = 175; // -
+ int ARETURN = 176; // -
+ int RETURN = 177; // -
+ int GETSTATIC = 178; // visitFieldInsn
+ int PUTSTATIC = 179; // -
+ int GETFIELD = 180; // -
+ int PUTFIELD = 181; // -
+ int INVOKEVIRTUAL = 182; // visitMethodInsn
+ int INVOKESPECIAL = 183; // -
+ int INVOKESTATIC = 184; // -
+ int INVOKEINTERFACE = 185; // -
+ int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
+ int NEW = 187; // visitTypeInsn
+ int NEWARRAY = 188; // visitIntInsn
+ int ANEWARRAY = 189; // visitTypeInsn
+ int ARRAYLENGTH = 190; // visitInsn
+ int ATHROW = 191; // -
+ int CHECKCAST = 192; // visitTypeInsn
+ int INSTANCEOF = 193; // -
+ int MONITORENTER = 194; // visitInsn
+ int MONITOREXIT = 195; // -
+ int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
+ int IFNULL = 198; // visitJumpInsn
+ int IFNONNULL = 199; // -
+}
diff --git a/asm/src/main/java/org/objectweb/asm/RecordComponentVisitor.java b/asm/src/main/java/org/objectweb/asm/RecordComponentVisitor.java
new file mode 100644
index 00000000..32784e2a
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/RecordComponentVisitor.java
@@ -0,0 +1,153 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a record component. The methods of this class must be called in the following
+ * order: ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code
+ * visitEnd}.
+ *
+ * @author Remi Forax
+ * @author Eric Bruneton
+ */
+public abstract class RecordComponentVisitor {
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of {@link
+ * Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ */
+ protected final int api;
+
+ /**
+ * The record visitor to which this visitor must delegate method calls. May be {@literal null}.
+ */
+ protected RecordComponentVisitor delegate;
+
+ /**
+ * Constructs a new {@link RecordComponentVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
+ * or {@link Opcodes#ASM9}.
+ */
+ protected RecordComponentVisitor(final int api) {
+ this(api, null);
+ }
+
+ /**
+ * Constructs a new {@link RecordComponentVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}.
+ * @param recordComponentVisitor the record component visitor to which this visitor must delegate
+ * method calls. May be null.
+ */
+ protected RecordComponentVisitor(
+ final int api, final RecordComponentVisitor recordComponentVisitor) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ if (api == Opcodes.ASM10_EXPERIMENTAL) {
+ Constants.checkAsmExperimental(this);
+ }
+ this.api = api;
+ this.delegate = recordComponentVisitor;
+ }
+
+ /**
+ * The record visitor to which this visitor must delegate method calls. May be {@literal null}.
+ *
+ * @return the record visitor to which this visitor must delegate method calls, or {@literal
+ * null}.
+ */
+ public RecordComponentVisitor getDelegate() {
+ return delegate;
+ }
+
+ /**
+ * Visits an annotation of the record component.
+ *
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (delegate != null) {
+ return delegate.visitAnnotation(descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits an annotation on a type in the record component signature.
+ *
+ * @param typeRef a reference to the annotated type. The sort of this type reference must be
+ * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
+ * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
+ * {@link TypeReference}.
+ * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
+ * static inner type within 'typeRef'. May be {@literal null} if the annotation targets
+ * 'typeRef' as a whole.
+ * @param descriptor the class descriptor of the annotation class.
+ * @param visible {@literal true} if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
+ * interested in visiting this annotation.
+ */
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (delegate != null) {
+ return delegate.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ return null;
+ }
+
+ /**
+ * Visits a non standard attribute of the record component.
+ *
+ * @param attribute an attribute.
+ */
+ public void visitAttribute(final Attribute attribute) {
+ if (delegate != null) {
+ delegate.visitAttribute(attribute);
+ }
+ }
+
+ /**
+ * Visits the end of the record component. This method, which is the last one to be called, is
+ * used to inform the visitor that everything have been visited.
+ */
+ public void visitEnd() {
+ if (delegate != null) {
+ delegate.visitEnd();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/RecordComponentWriter.java b/asm/src/main/java/org/objectweb/asm/RecordComponentWriter.java
new file mode 100644
index 00000000..0dabb754
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/RecordComponentWriter.java
@@ -0,0 +1,225 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+final class RecordComponentWriter extends RecordComponentVisitor {
+ /** Where the constants used in this RecordComponentWriter must be stored. */
+ private final SymbolTable symbolTable;
+
+ // Note: fields are ordered as in the record_component_info structure, and those related to
+ // attributes are ordered as in Section 4.7 of the JVMS.
+
+ /** The name_index field of the Record attribute. */
+ private final int nameIndex;
+
+ /** The descriptor_index field of the Record attribute. */
+ private final int descriptorIndex;
+
+ /**
+ * The signature_index field of the Signature attribute of this record component, or 0 if there is
+ * no Signature attribute.
+ */
+ private int signatureIndex;
+
+ /**
+ * The last runtime visible annotation of this record component. The previous ones can be accessed
+ * with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleAnnotation;
+
+ /**
+ * The last runtime invisible annotation of this record component. The previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleAnnotation;
+
+ /**
+ * The last runtime visible type annotation of this record component. The previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeVisibleTypeAnnotation;
+
+ /**
+ * The last runtime invisible type annotation of this record component. The previous ones can be
+ * accessed with the {@link AnnotationWriter#previousAnnotation} field. May be {@literal null}.
+ */
+ private AnnotationWriter lastRuntimeInvisibleTypeAnnotation;
+
+ /**
+ * The first non standard attribute of this record component. The next ones can be accessed with
+ * the {@link Attribute#nextAttribute} field. May be {@literal null}.
+ *
+ * <p><b>WARNING</b>: this list stores the attributes in the <i>reverse</i> order of their visit.
+ * firstAttribute is actually the last attribute visited in {@link #visitAttribute(Attribute)}.
+ * The {@link #putRecordComponentInfo(ByteVector)} method writes the attributes in the order
+ * defined by this list, i.e. in the reverse order specified by the user.
+ */
+ private Attribute firstAttribute;
+
+ /**
+ * Constructs a new {@link RecordComponentWriter}.
+ *
+ * @param symbolTable where the constants used in this RecordComponentWriter must be stored.
+ * @param name the record component name.
+ * @param descriptor the record component descriptor (see {@link Type}).
+ * @param signature the record component signature. May be {@literal null}.
+ */
+ RecordComponentWriter(
+ final SymbolTable symbolTable,
+ final String name,
+ final String descriptor,
+ final String signature) {
+ super(/* latest api = */ Opcodes.ASM9);
+ this.symbolTable = symbolTable;
+ this.nameIndex = symbolTable.addConstantUtf8(name);
+ this.descriptorIndex = symbolTable.addConstantUtf8(descriptor);
+ if (signature != null) {
+ this.signatureIndex = symbolTable.addConstantUtf8(signature);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the FieldVisitor abstract class
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeVisibleAnnotation);
+ } else {
+ return lastRuntimeInvisibleAnnotation =
+ AnnotationWriter.create(symbolTable, descriptor, lastRuntimeInvisibleAnnotation);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+ if (visible) {
+ return lastRuntimeVisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeVisibleTypeAnnotation);
+ } else {
+ return lastRuntimeInvisibleTypeAnnotation =
+ AnnotationWriter.create(
+ symbolTable, typeRef, typePath, descriptor, lastRuntimeInvisibleTypeAnnotation);
+ }
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attribute) {
+ // Store the attributes in the <i>reverse</i> order of their visit by this method.
+ attribute.nextAttribute = firstAttribute;
+ firstAttribute = attribute;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Nothing to do.
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the size of the record component JVMS structure generated by this
+ * RecordComponentWriter. Also adds the names of the attributes of this record component in the
+ * constant pool.
+ *
+ * @return the size in bytes of the record_component_info of the Record attribute.
+ */
+ int computeRecordComponentInfoSize() {
+ // name_index, descriptor_index and attributes_count fields use 6 bytes.
+ int size = 6;
+ size += Attribute.computeAttributesSize(symbolTable, 0, signatureIndex);
+ size +=
+ AnnotationWriter.computeAnnotationsSize(
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation);
+ if (firstAttribute != null) {
+ size += firstAttribute.computeAttributesSize(symbolTable);
+ }
+ return size;
+ }
+
+ /**
+ * Puts the content of the record component generated by this RecordComponentWriter into the given
+ * ByteVector.
+ *
+ * @param output where the record_component_info structure must be put.
+ */
+ void putRecordComponentInfo(final ByteVector output) {
+ output.putShort(nameIndex).putShort(descriptorIndex);
+ // Compute and put the attributes_count field.
+ // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
+ int attributesCount = 0;
+ if (signatureIndex != 0) {
+ ++attributesCount;
+ }
+ if (lastRuntimeVisibleAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeInvisibleAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeVisibleTypeAnnotation != null) {
+ ++attributesCount;
+ }
+ if (lastRuntimeInvisibleTypeAnnotation != null) {
+ ++attributesCount;
+ }
+ if (firstAttribute != null) {
+ attributesCount += firstAttribute.getAttributeCount();
+ }
+ output.putShort(attributesCount);
+ Attribute.putAttributes(symbolTable, 0, signatureIndex, output);
+ AnnotationWriter.putAnnotations(
+ symbolTable,
+ lastRuntimeVisibleAnnotation,
+ lastRuntimeInvisibleAnnotation,
+ lastRuntimeVisibleTypeAnnotation,
+ lastRuntimeInvisibleTypeAnnotation,
+ output);
+ if (firstAttribute != null) {
+ firstAttribute.putAttributes(symbolTable, output);
+ }
+ }
+
+ /**
+ * Collects the attributes of this record component into the given set of attribute prototypes.
+ *
+ * @param attributePrototypes a set of attribute prototypes.
+ */
+ final void collectAttributePrototypes(final Attribute.Set attributePrototypes) {
+ attributePrototypes.addAttributes(firstAttribute);
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Symbol.java b/asm/src/main/java/org/objectweb/asm/Symbol.java
new file mode 100644
index 00000000..b1dd5eb0
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Symbol.java
@@ -0,0 +1,243 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * An entry of the constant pool, of the BootstrapMethods attribute, or of the (ASM specific) type
+ * table of a class.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4">JVMS
+ * 4.4</a>
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23">JVMS
+ * 4.7.23</a>
+ * @author Eric Bruneton
+ */
+abstract class Symbol {
+
+ // Tag values for the constant pool entries (using the same order as in the JVMS).
+
+ /** The tag value of CONSTANT_Class_info JVMS structures. */
+ static final int CONSTANT_CLASS_TAG = 7;
+
+ /** The tag value of CONSTANT_Fieldref_info JVMS structures. */
+ static final int CONSTANT_FIELDREF_TAG = 9;
+
+ /** The tag value of CONSTANT_Methodref_info JVMS structures. */
+ static final int CONSTANT_METHODREF_TAG = 10;
+
+ /** The tag value of CONSTANT_InterfaceMethodref_info JVMS structures. */
+ static final int CONSTANT_INTERFACE_METHODREF_TAG = 11;
+
+ /** The tag value of CONSTANT_String_info JVMS structures. */
+ static final int CONSTANT_STRING_TAG = 8;
+
+ /** The tag value of CONSTANT_Integer_info JVMS structures. */
+ static final int CONSTANT_INTEGER_TAG = 3;
+
+ /** The tag value of CONSTANT_Float_info JVMS structures. */
+ static final int CONSTANT_FLOAT_TAG = 4;
+
+ /** The tag value of CONSTANT_Long_info JVMS structures. */
+ static final int CONSTANT_LONG_TAG = 5;
+
+ /** The tag value of CONSTANT_Double_info JVMS structures. */
+ static final int CONSTANT_DOUBLE_TAG = 6;
+
+ /** The tag value of CONSTANT_NameAndType_info JVMS structures. */
+ static final int CONSTANT_NAME_AND_TYPE_TAG = 12;
+
+ /** The tag value of CONSTANT_Utf8_info JVMS structures. */
+ static final int CONSTANT_UTF8_TAG = 1;
+
+ /** The tag value of CONSTANT_MethodHandle_info JVMS structures. */
+ static final int CONSTANT_METHOD_HANDLE_TAG = 15;
+
+ /** The tag value of CONSTANT_MethodType_info JVMS structures. */
+ static final int CONSTANT_METHOD_TYPE_TAG = 16;
+
+ /** The tag value of CONSTANT_Dynamic_info JVMS structures. */
+ static final int CONSTANT_DYNAMIC_TAG = 17;
+
+ /** The tag value of CONSTANT_InvokeDynamic_info JVMS structures. */
+ static final int CONSTANT_INVOKE_DYNAMIC_TAG = 18;
+
+ /** The tag value of CONSTANT_Module_info JVMS structures. */
+ static final int CONSTANT_MODULE_TAG = 19;
+
+ /** The tag value of CONSTANT_Package_info JVMS structures. */
+ static final int CONSTANT_PACKAGE_TAG = 20;
+
+ // Tag values for the BootstrapMethods attribute entries (ASM specific tag).
+
+ /** The tag value of the BootstrapMethods attribute entries. */
+ static final int BOOTSTRAP_METHOD_TAG = 64;
+
+ // Tag values for the type table entries (ASM specific tags).
+
+ /** The tag value of a normal type entry in the (ASM specific) type table of a class. */
+ static final int TYPE_TAG = 128;
+
+ /**
+ * The tag value of an {@link Frame#ITEM_UNINITIALIZED} type entry in the type table of a class.
+ */
+ static final int UNINITIALIZED_TYPE_TAG = 129;
+
+ /** The tag value of a merged type entry in the (ASM specific) type table of a class. */
+ static final int MERGED_TYPE_TAG = 130;
+
+ // Instance fields.
+
+ /**
+ * The index of this symbol in the constant pool, in the BootstrapMethods attribute, or in the
+ * (ASM specific) type table of a class (depending on the {@link #tag} value).
+ */
+ final int index;
+
+ /**
+ * A tag indicating the type of this symbol. Must be one of the static tag values defined in this
+ * class.
+ */
+ final int tag;
+
+ /**
+ * The internal name of the owner class of this symbol. Only used for {@link
+ * #CONSTANT_FIELDREF_TAG}, {@link #CONSTANT_METHODREF_TAG}, {@link
+ * #CONSTANT_INTERFACE_METHODREF_TAG}, and {@link #CONSTANT_METHOD_HANDLE_TAG} symbols.
+ */
+ final String owner;
+
+ /**
+ * The name of the class field or method corresponding to this symbol. Only used for {@link
+ * #CONSTANT_FIELDREF_TAG}, {@link #CONSTANT_METHODREF_TAG}, {@link
+ * #CONSTANT_INTERFACE_METHODREF_TAG}, {@link #CONSTANT_NAME_AND_TYPE_TAG}, {@link
+ * #CONSTANT_METHOD_HANDLE_TAG}, {@link #CONSTANT_DYNAMIC_TAG} and {@link
+ * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols.
+ */
+ final String name;
+
+ /**
+ * The string value of this symbol. This is:
+ *
+ * <ul>
+ * <li>a field or method descriptor for {@link #CONSTANT_FIELDREF_TAG}, {@link
+ * #CONSTANT_METHODREF_TAG}, {@link #CONSTANT_INTERFACE_METHODREF_TAG}, {@link
+ * #CONSTANT_NAME_AND_TYPE_TAG}, {@link #CONSTANT_METHOD_HANDLE_TAG}, {@link
+ * #CONSTANT_METHOD_TYPE_TAG}, {@link #CONSTANT_DYNAMIC_TAG} and {@link
+ * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols,
+ * <li>an arbitrary string for {@link #CONSTANT_UTF8_TAG} and {@link #CONSTANT_STRING_TAG}
+ * symbols,
+ * <li>an internal class name for {@link #CONSTANT_CLASS_TAG}, {@link #TYPE_TAG} and {@link
+ * #UNINITIALIZED_TYPE_TAG} symbols,
+ * <li>{@literal null} for the other types of symbol.
+ * </ul>
+ */
+ final String value;
+
+ /**
+ * The numeric value of this symbol. This is:
+ *
+ * <ul>
+ * <li>the symbol's value for {@link #CONSTANT_INTEGER_TAG},{@link #CONSTANT_FLOAT_TAG}, {@link
+ * #CONSTANT_LONG_TAG}, {@link #CONSTANT_DOUBLE_TAG},
+ * <li>the CONSTANT_MethodHandle_info reference_kind field value for {@link
+ * #CONSTANT_METHOD_HANDLE_TAG} symbols,
+ * <li>the CONSTANT_InvokeDynamic_info bootstrap_method_attr_index field value for {@link
+ * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols,
+ * <li>the offset of a bootstrap method in the BootstrapMethods boostrap_methods array, for
+ * {@link #CONSTANT_DYNAMIC_TAG} or {@link #BOOTSTRAP_METHOD_TAG} symbols,
+ * <li>the bytecode offset of the NEW instruction that created an {@link
+ * Frame#ITEM_UNINITIALIZED} type for {@link #UNINITIALIZED_TYPE_TAG} symbols,
+ * <li>the indices (in the class' type table) of two {@link #TYPE_TAG} source types for {@link
+ * #MERGED_TYPE_TAG} symbols,
+ * <li>0 for the other types of symbol.
+ * </ul>
+ */
+ final long data;
+
+ /**
+ * Additional information about this symbol, generally computed lazily. <i>Warning: the value of
+ * this field is ignored when comparing Symbol instances</i> (to avoid duplicate entries in a
+ * SymbolTable). Therefore, this field should only contain data that can be computed from the
+ * other fields of this class. It contains:
+ *
+ * <ul>
+ * <li>the {@link Type#getArgumentsAndReturnSizes} of the symbol's method descriptor for {@link
+ * #CONSTANT_METHODREF_TAG}, {@link #CONSTANT_INTERFACE_METHODREF_TAG} and {@link
+ * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols,
+ * <li>the index in the InnerClasses_attribute 'classes' array (plus one) corresponding to this
+ * class, for {@link #CONSTANT_CLASS_TAG} symbols,
+ * <li>the index (in the class' type table) of the merged type of the two source types for
+ * {@link #MERGED_TYPE_TAG} symbols,
+ * <li>0 for the other types of symbol, or if this field has not been computed yet.
+ * </ul>
+ */
+ int info;
+
+ /**
+ * Constructs a new Symbol. This constructor can't be used directly because the Symbol class is
+ * abstract. Instead, use the factory methods of the {@link SymbolTable} class.
+ *
+ * @param index the symbol index in the constant pool, in the BootstrapMethods attribute, or in
+ * the (ASM specific) type table of a class (depending on 'tag').
+ * @param tag the symbol type. Must be one of the static tag values defined in this class.
+ * @param owner The internal name of the symbol's owner class. Maybe {@literal null}.
+ * @param name The name of the symbol's corresponding class field or method. Maybe {@literal
+ * null}.
+ * @param value The string value of this symbol. Maybe {@literal null}.
+ * @param data The numeric value of this symbol.
+ */
+ Symbol(
+ final int index,
+ final int tag,
+ final String owner,
+ final String name,
+ final String value,
+ final long data) {
+ this.index = index;
+ this.tag = tag;
+ this.owner = owner;
+ this.name = name;
+ this.value = value;
+ this.data = data;
+ }
+
+ /**
+ * Returns the result {@link Type#getArgumentsAndReturnSizes} on {@link #value}.
+ *
+ * @return the result {@link Type#getArgumentsAndReturnSizes} on {@link #value} (memoized in
+ * {@link #info} for efficiency). This should only be used for {@link
+ * #CONSTANT_METHODREF_TAG}, {@link #CONSTANT_INTERFACE_METHODREF_TAG} and {@link
+ * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols.
+ */
+ int getArgumentsAndReturnSizes() {
+ if (info == 0) {
+ info = Type.getArgumentsAndReturnSizes(value);
+ }
+ return info;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/SymbolTable.java b/asm/src/main/java/org/objectweb/asm/SymbolTable.java
new file mode 100644
index 00000000..a2f26f18
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/SymbolTable.java
@@ -0,0 +1,1322 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * The constant pool entries, the BootstrapMethods attribute entries and the (ASM specific) type
+ * table entries of a class.
+ *
+ * @author Eric Bruneton
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4">JVMS
+ * 4.4</a>
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23">JVMS
+ * 4.7.23</a>
+ */
+final class SymbolTable {
+
+ /**
+ * The ClassWriter to which this SymbolTable belongs. This is only used to get access to {@link
+ * ClassWriter#getCommonSuperClass} and to serialize custom attributes with {@link
+ * Attribute#write}.
+ */
+ final ClassWriter classWriter;
+
+ /**
+ * The ClassReader from which this SymbolTable was constructed, or {@literal null} if it was
+ * constructed from scratch.
+ */
+ private final ClassReader sourceClassReader;
+
+ /** The major version number of the class to which this symbol table belongs. */
+ private int majorVersion;
+
+ /** The internal name of the class to which this symbol table belongs. */
+ private String className;
+
+ /**
+ * The total number of {@link Entry} instances in {@link #entries}. This includes entries that are
+ * accessible (recursively) via {@link Entry#next}.
+ */
+ private int entryCount;
+
+ /**
+ * A hash set of all the entries in this SymbolTable (this includes the constant pool entries, the
+ * bootstrap method entries and the type table entries). Each {@link Entry} instance is stored at
+ * the array index given by its hash code modulo the array size. If several entries must be stored
+ * at the same array index, they are linked together via their {@link Entry#next} field. The
+ * factory methods of this class make sure that this table does not contain duplicated entries.
+ */
+ private Entry[] entries;
+
+ /**
+ * The number of constant pool items in {@link #constantPool}, plus 1. The first constant pool
+ * item has index 1, and long and double items count for two items.
+ */
+ private int constantPoolCount;
+
+ /**
+ * The content of the ClassFile's constant_pool JVMS structure corresponding to this SymbolTable.
+ * The ClassFile's constant_pool_count field is <i>not</i> included.
+ */
+ private ByteVector constantPool;
+
+ /**
+ * The number of bootstrap methods in {@link #bootstrapMethods}. Corresponds to the
+ * BootstrapMethods_attribute's num_bootstrap_methods field value.
+ */
+ private int bootstrapMethodCount;
+
+ /**
+ * The content of the BootstrapMethods attribute 'bootstrap_methods' array corresponding to this
+ * SymbolTable. Note that the first 6 bytes of the BootstrapMethods_attribute, and its
+ * num_bootstrap_methods field, are <i>not</i> included.
+ */
+ private ByteVector bootstrapMethods;
+
+ /**
+ * The actual number of elements in {@link #typeTable}. These elements are stored from index 0 to
+ * typeCount (excluded). The other array entries are empty.
+ */
+ private int typeCount;
+
+ /**
+ * An ASM specific type table used to temporarily store internal names that will not necessarily
+ * be stored in the constant pool. This type table is used by the control flow and data flow
+ * analysis algorithm used to compute stack map frames from scratch. This array stores {@link
+ * Symbol#TYPE_TAG} and {@link Symbol#UNINITIALIZED_TYPE_TAG}) Symbol. The type symbol at index
+ * {@code i} has its {@link Symbol#index} equal to {@code i} (and vice versa).
+ */
+ private Entry[] typeTable;
+
+ /**
+ * Constructs a new, empty SymbolTable for the given ClassWriter.
+ *
+ * @param classWriter a ClassWriter.
+ */
+ SymbolTable(final ClassWriter classWriter) {
+ this.classWriter = classWriter;
+ this.sourceClassReader = null;
+ this.entries = new Entry[256];
+ this.constantPoolCount = 1;
+ this.constantPool = new ByteVector();
+ }
+
+ /**
+ * Constructs a new SymbolTable for the given ClassWriter, initialized with the constant pool and
+ * bootstrap methods of the given ClassReader.
+ *
+ * @param classWriter a ClassWriter.
+ * @param classReader the ClassReader whose constant pool and bootstrap methods must be copied to
+ * initialize the SymbolTable.
+ */
+ SymbolTable(final ClassWriter classWriter, final ClassReader classReader) {
+ this.classWriter = classWriter;
+ this.sourceClassReader = classReader;
+
+ // Copy the constant pool binary content.
+ byte[] inputBytes = classReader.classFileBuffer;
+ int constantPoolOffset = classReader.getItem(1) - 1;
+ int constantPoolLength = classReader.header - constantPoolOffset;
+ constantPoolCount = classReader.getItemCount();
+ constantPool = new ByteVector(constantPoolLength);
+ constantPool.putByteArray(inputBytes, constantPoolOffset, constantPoolLength);
+
+ // Add the constant pool items in the symbol table entries. Reserve enough space in 'entries' to
+ // avoid too many hash set collisions (entries is not dynamically resized by the addConstant*
+ // method calls below), and to account for bootstrap method entries.
+ entries = new Entry[constantPoolCount * 2];
+ char[] charBuffer = new char[classReader.getMaxStringLength()];
+ boolean hasBootstrapMethods = false;
+ int itemIndex = 1;
+ while (itemIndex < constantPoolCount) {
+ int itemOffset = classReader.getItem(itemIndex);
+ int itemTag = inputBytes[itemOffset - 1];
+ int nameAndTypeItemOffset;
+ switch (itemTag) {
+ case Symbol.CONSTANT_FIELDREF_TAG:
+ case Symbol.CONSTANT_METHODREF_TAG:
+ case Symbol.CONSTANT_INTERFACE_METHODREF_TAG:
+ nameAndTypeItemOffset =
+ classReader.getItem(classReader.readUnsignedShort(itemOffset + 2));
+ addConstantMemberReference(
+ itemIndex,
+ itemTag,
+ classReader.readClass(itemOffset, charBuffer),
+ classReader.readUTF8(nameAndTypeItemOffset, charBuffer),
+ classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer));
+ break;
+ case Symbol.CONSTANT_INTEGER_TAG:
+ case Symbol.CONSTANT_FLOAT_TAG:
+ addConstantIntegerOrFloat(itemIndex, itemTag, classReader.readInt(itemOffset));
+ break;
+ case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
+ addConstantNameAndType(
+ itemIndex,
+ classReader.readUTF8(itemOffset, charBuffer),
+ classReader.readUTF8(itemOffset + 2, charBuffer));
+ break;
+ case Symbol.CONSTANT_LONG_TAG:
+ case Symbol.CONSTANT_DOUBLE_TAG:
+ addConstantLongOrDouble(itemIndex, itemTag, classReader.readLong(itemOffset));
+ break;
+ case Symbol.CONSTANT_UTF8_TAG:
+ addConstantUtf8(itemIndex, classReader.readUtf(itemIndex, charBuffer));
+ break;
+ case Symbol.CONSTANT_METHOD_HANDLE_TAG:
+ int memberRefItemOffset =
+ classReader.getItem(classReader.readUnsignedShort(itemOffset + 1));
+ nameAndTypeItemOffset =
+ classReader.getItem(classReader.readUnsignedShort(memberRefItemOffset + 2));
+ addConstantMethodHandle(
+ itemIndex,
+ classReader.readByte(itemOffset),
+ classReader.readClass(memberRefItemOffset, charBuffer),
+ classReader.readUTF8(nameAndTypeItemOffset, charBuffer),
+ classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer));
+ break;
+ case Symbol.CONSTANT_DYNAMIC_TAG:
+ case Symbol.CONSTANT_INVOKE_DYNAMIC_TAG:
+ hasBootstrapMethods = true;
+ nameAndTypeItemOffset =
+ classReader.getItem(classReader.readUnsignedShort(itemOffset + 2));
+ addConstantDynamicOrInvokeDynamicReference(
+ itemTag,
+ itemIndex,
+ classReader.readUTF8(nameAndTypeItemOffset, charBuffer),
+ classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer),
+ classReader.readUnsignedShort(itemOffset));
+ break;
+ case Symbol.CONSTANT_STRING_TAG:
+ case Symbol.CONSTANT_CLASS_TAG:
+ case Symbol.CONSTANT_METHOD_TYPE_TAG:
+ case Symbol.CONSTANT_MODULE_TAG:
+ case Symbol.CONSTANT_PACKAGE_TAG:
+ addConstantUtf8Reference(
+ itemIndex, itemTag, classReader.readUTF8(itemOffset, charBuffer));
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ itemIndex +=
+ (itemTag == Symbol.CONSTANT_LONG_TAG || itemTag == Symbol.CONSTANT_DOUBLE_TAG) ? 2 : 1;
+ }
+
+ // Copy the BootstrapMethods, if any.
+ if (hasBootstrapMethods) {
+ copyBootstrapMethods(classReader, charBuffer);
+ }
+ }
+
+ /**
+ * Read the BootstrapMethods 'bootstrap_methods' array binary content and add them as entries of
+ * the SymbolTable.
+ *
+ * @param classReader the ClassReader whose bootstrap methods must be copied to initialize the
+ * SymbolTable.
+ * @param charBuffer a buffer used to read strings in the constant pool.
+ */
+ private void copyBootstrapMethods(final ClassReader classReader, final char[] charBuffer) {
+ // Find attributOffset of the 'bootstrap_methods' array.
+ byte[] inputBytes = classReader.classFileBuffer;
+ int currentAttributeOffset = classReader.getFirstAttributeOffset();
+ for (int i = classReader.readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
+ String attributeName = classReader.readUTF8(currentAttributeOffset, charBuffer);
+ if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
+ bootstrapMethodCount = classReader.readUnsignedShort(currentAttributeOffset + 6);
+ break;
+ }
+ currentAttributeOffset += 6 + classReader.readInt(currentAttributeOffset + 2);
+ }
+ if (bootstrapMethodCount > 0) {
+ // Compute the offset and the length of the BootstrapMethods 'bootstrap_methods' array.
+ int bootstrapMethodsOffset = currentAttributeOffset + 8;
+ int bootstrapMethodsLength = classReader.readInt(currentAttributeOffset + 2) - 2;
+ bootstrapMethods = new ByteVector(bootstrapMethodsLength);
+ bootstrapMethods.putByteArray(inputBytes, bootstrapMethodsOffset, bootstrapMethodsLength);
+
+ // Add each bootstrap method in the symbol table entries.
+ int currentOffset = bootstrapMethodsOffset;
+ for (int i = 0; i < bootstrapMethodCount; i++) {
+ int offset = currentOffset - bootstrapMethodsOffset;
+ int bootstrapMethodRef = classReader.readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ int numBootstrapArguments = classReader.readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ int hashCode = classReader.readConst(bootstrapMethodRef, charBuffer).hashCode();
+ while (numBootstrapArguments-- > 0) {
+ int bootstrapArgument = classReader.readUnsignedShort(currentOffset);
+ currentOffset += 2;
+ hashCode ^= classReader.readConst(bootstrapArgument, charBuffer).hashCode();
+ }
+ add(new Entry(i, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode & 0x7FFFFFFF));
+ }
+ }
+ }
+
+ /**
+ * Returns the ClassReader from which this SymbolTable was constructed.
+ *
+ * @return the ClassReader from which this SymbolTable was constructed, or {@literal null} if it
+ * was constructed from scratch.
+ */
+ ClassReader getSource() {
+ return sourceClassReader;
+ }
+
+ /**
+ * Returns the major version of the class to which this symbol table belongs.
+ *
+ * @return the major version of the class to which this symbol table belongs.
+ */
+ int getMajorVersion() {
+ return majorVersion;
+ }
+
+ /**
+ * Returns the internal name of the class to which this symbol table belongs.
+ *
+ * @return the internal name of the class to which this symbol table belongs.
+ */
+ String getClassName() {
+ return className;
+ }
+
+ /**
+ * Sets the major version and the name of the class to which this symbol table belongs. Also adds
+ * the class name to the constant pool.
+ *
+ * @param majorVersion a major ClassFile version number.
+ * @param className an internal class name.
+ * @return the constant pool index of a new or already existing Symbol with the given class name.
+ */
+ int setMajorVersionAndClassName(final int majorVersion, final String className) {
+ this.majorVersion = majorVersion;
+ this.className = className;
+ return addConstantClass(className).index;
+ }
+
+ /**
+ * Returns the number of items in this symbol table's constant_pool array (plus 1).
+ *
+ * @return the number of items in this symbol table's constant_pool array (plus 1).
+ */
+ int getConstantPoolCount() {
+ return constantPoolCount;
+ }
+
+ /**
+ * Returns the length in bytes of this symbol table's constant_pool array.
+ *
+ * @return the length in bytes of this symbol table's constant_pool array.
+ */
+ int getConstantPoolLength() {
+ return constantPool.length;
+ }
+
+ /**
+ * Puts this symbol table's constant_pool array in the given ByteVector, preceded by the
+ * constant_pool_count value.
+ *
+ * @param output where the JVMS ClassFile's constant_pool array must be put.
+ */
+ void putConstantPool(final ByteVector output) {
+ output.putShort(constantPoolCount).putByteArray(constantPool.data, 0, constantPool.length);
+ }
+
+ /**
+ * Returns the size in bytes of this symbol table's BootstrapMethods attribute. Also adds the
+ * attribute name in the constant pool.
+ *
+ * @return the size in bytes of this symbol table's BootstrapMethods attribute.
+ */
+ int computeBootstrapMethodsSize() {
+ if (bootstrapMethods != null) {
+ addConstantUtf8(Constants.BOOTSTRAP_METHODS);
+ return 8 + bootstrapMethods.length;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Puts this symbol table's BootstrapMethods attribute in the given ByteVector. This includes the
+ * 6 attribute header bytes and the num_bootstrap_methods value.
+ *
+ * @param output where the JVMS BootstrapMethods attribute must be put.
+ */
+ void putBootstrapMethods(final ByteVector output) {
+ if (bootstrapMethods != null) {
+ output
+ .putShort(addConstantUtf8(Constants.BOOTSTRAP_METHODS))
+ .putInt(bootstrapMethods.length + 2)
+ .putShort(bootstrapMethodCount)
+ .putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Generic symbol table entries management.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the list of entries which can potentially have the given hash code.
+ *
+ * @param hashCode a {@link Entry#hashCode} value.
+ * @return the list of entries which can potentially have the given hash code. The list is stored
+ * via the {@link Entry#next} field.
+ */
+ private Entry get(final int hashCode) {
+ return entries[hashCode % entries.length];
+ }
+
+ /**
+ * Puts the given entry in the {@link #entries} hash set. This method does <i>not</i> check
+ * whether {@link #entries} already contains a similar entry or not. {@link #entries} is resized
+ * if necessary to avoid hash collisions (multiple entries needing to be stored at the same {@link
+ * #entries} array index) as much as possible, with reasonable memory usage.
+ *
+ * @param entry an Entry (which must not already be contained in {@link #entries}).
+ * @return the given entry
+ */
+ private Entry put(final Entry entry) {
+ if (entryCount > (entries.length * 3) / 4) {
+ int currentCapacity = entries.length;
+ int newCapacity = currentCapacity * 2 + 1;
+ Entry[] newEntries = new Entry[newCapacity];
+ for (int i = currentCapacity - 1; i >= 0; --i) {
+ Entry currentEntry = entries[i];
+ while (currentEntry != null) {
+ int newCurrentEntryIndex = currentEntry.hashCode % newCapacity;
+ Entry nextEntry = currentEntry.next;
+ currentEntry.next = newEntries[newCurrentEntryIndex];
+ newEntries[newCurrentEntryIndex] = currentEntry;
+ currentEntry = nextEntry;
+ }
+ }
+ entries = newEntries;
+ }
+ entryCount++;
+ int index = entry.hashCode % entries.length;
+ entry.next = entries[index];
+ return entries[index] = entry;
+ }
+
+ /**
+ * Adds the given entry in the {@link #entries} hash set. This method does <i>not</i> check
+ * whether {@link #entries} already contains a similar entry or not, and does <i>not</i> resize
+ * {@link #entries} if necessary.
+ *
+ * @param entry an Entry (which must not already be contained in {@link #entries}).
+ */
+ private void add(final Entry entry) {
+ entryCount++;
+ int index = entry.hashCode % entries.length;
+ entry.next = entries[index];
+ entries[index] = entry;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Constant pool entries management.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds a number or string constant to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value the value of the constant to be added to the constant pool. This parameter must be
+ * an {@link Integer}, {@link Byte}, {@link Character}, {@link Short}, {@link Boolean}, {@link
+ * Float}, {@link Long}, {@link Double}, {@link String}, {@link Type} or {@link Handle}.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstant(final Object value) {
+ if (value instanceof Integer) {
+ return addConstantInteger(((Integer) value).intValue());
+ } else if (value instanceof Byte) {
+ return addConstantInteger(((Byte) value).intValue());
+ } else if (value instanceof Character) {
+ return addConstantInteger(((Character) value).charValue());
+ } else if (value instanceof Short) {
+ return addConstantInteger(((Short) value).intValue());
+ } else if (value instanceof Boolean) {
+ return addConstantInteger(((Boolean) value).booleanValue() ? 1 : 0);
+ } else if (value instanceof Float) {
+ return addConstantFloat(((Float) value).floatValue());
+ } else if (value instanceof Long) {
+ return addConstantLong(((Long) value).longValue());
+ } else if (value instanceof Double) {
+ return addConstantDouble(((Double) value).doubleValue());
+ } else if (value instanceof String) {
+ return addConstantString((String) value);
+ } else if (value instanceof Type) {
+ Type type = (Type) value;
+ int typeSort = type.getSort();
+ if (typeSort == Type.OBJECT) {
+ return addConstantClass(type.getInternalName());
+ } else if (typeSort == Type.METHOD) {
+ return addConstantMethodType(type.getDescriptor());
+ } else { // type is a primitive or array type.
+ return addConstantClass(type.getDescriptor());
+ }
+ } else if (value instanceof Handle) {
+ Handle handle = (Handle) value;
+ return addConstantMethodHandle(
+ handle.getTag(),
+ handle.getOwner(),
+ handle.getName(),
+ handle.getDesc(),
+ handle.isInterface());
+ } else if (value instanceof ConstantDynamic) {
+ ConstantDynamic constantDynamic = (ConstantDynamic) value;
+ return addConstantDynamic(
+ constantDynamic.getName(),
+ constantDynamic.getDescriptor(),
+ constantDynamic.getBootstrapMethod(),
+ constantDynamic.getBootstrapMethodArgumentsUnsafe());
+ } else {
+ throw new IllegalArgumentException("value " + value);
+ }
+ }
+
+ /**
+ * Adds a CONSTANT_Class_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value the internal name of a class.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantClass(final String value) {
+ return addConstantUtf8Reference(Symbol.CONSTANT_CLASS_TAG, value);
+ }
+
+ /**
+ * Adds a CONSTANT_Fieldref_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param owner the internal name of a class.
+ * @param name a field name.
+ * @param descriptor a field descriptor.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantFieldref(final String owner, final String name, final String descriptor) {
+ return addConstantMemberReference(Symbol.CONSTANT_FIELDREF_TAG, owner, name, descriptor);
+ }
+
+ /**
+ * Adds a CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info to the constant pool of this
+ * symbol table. Does nothing if the constant pool already contains a similar item.
+ *
+ * @param owner the internal name of a class.
+ * @param name a method name.
+ * @param descriptor a method descriptor.
+ * @param isInterface whether owner is an interface or not.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantMethodref(
+ final String owner, final String name, final String descriptor, final boolean isInterface) {
+ int tag = isInterface ? Symbol.CONSTANT_INTERFACE_METHODREF_TAG : Symbol.CONSTANT_METHODREF_TAG;
+ return addConstantMemberReference(tag, owner, name, descriptor);
+ }
+
+ /**
+ * Adds a CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info to
+ * the constant pool of this symbol table. Does nothing if the constant pool already contains a
+ * similar item.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG}
+ * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}.
+ * @param owner the internal name of a class.
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ * @return a new or already existing Symbol with the given value.
+ */
+ private Entry addConstantMemberReference(
+ final int tag, final String owner, final String name, final String descriptor) {
+ int hashCode = hash(tag, owner, name, descriptor);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag
+ && entry.hashCode == hashCode
+ && entry.owner.equals(owner)
+ && entry.name.equals(name)
+ && entry.value.equals(descriptor)) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ constantPool.put122(
+ tag, addConstantClass(owner).index, addConstantNameAndType(name, descriptor));
+ return put(new Entry(constantPoolCount++, tag, owner, name, descriptor, 0, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info
+ * to the constant pool of this symbol table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG}
+ * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}.
+ * @param owner the internal name of a class.
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ */
+ private void addConstantMemberReference(
+ final int index,
+ final int tag,
+ final String owner,
+ final String name,
+ final String descriptor) {
+ add(new Entry(index, tag, owner, name, descriptor, 0, hash(tag, owner, name, descriptor)));
+ }
+
+ /**
+ * Adds a CONSTANT_String_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value a string.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantString(final String value) {
+ return addConstantUtf8Reference(Symbol.CONSTANT_STRING_TAG, value);
+ }
+
+ /**
+ * Adds a CONSTANT_Integer_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value an int.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantInteger(final int value) {
+ return addConstantIntegerOrFloat(Symbol.CONSTANT_INTEGER_TAG, value);
+ }
+
+ /**
+ * Adds a CONSTANT_Float_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value a float.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantFloat(final float value) {
+ return addConstantIntegerOrFloat(Symbol.CONSTANT_FLOAT_TAG, Float.floatToRawIntBits(value));
+ }
+
+ /**
+ * Adds a CONSTANT_Integer_info or CONSTANT_Float_info to the constant pool of this symbol table.
+ * Does nothing if the constant pool already contains a similar item.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}.
+ * @param value an int or float.
+ * @return a constant pool constant with the given tag and primitive values.
+ */
+ private Symbol addConstantIntegerOrFloat(final int tag, final int value) {
+ int hashCode = hash(tag, value);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ constantPool.putByte(tag).putInt(value);
+ return put(new Entry(constantPoolCount++, tag, value, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_Integer_info or CONSTANT_Float_info to the constant pool of this symbol
+ * table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param tag one of {@link Symbol#CONSTANT_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}.
+ * @param value an int or float.
+ */
+ private void addConstantIntegerOrFloat(final int index, final int tag, final int value) {
+ add(new Entry(index, tag, value, hash(tag, value)));
+ }
+
+ /**
+ * Adds a CONSTANT_Long_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value a long.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantLong(final long value) {
+ return addConstantLongOrDouble(Symbol.CONSTANT_LONG_TAG, value);
+ }
+
+ /**
+ * Adds a CONSTANT_Double_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value a double.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantDouble(final double value) {
+ return addConstantLongOrDouble(Symbol.CONSTANT_DOUBLE_TAG, Double.doubleToRawLongBits(value));
+ }
+
+ /**
+ * Adds a CONSTANT_Long_info or CONSTANT_Double_info to the constant pool of this symbol table.
+ * Does nothing if the constant pool already contains a similar item.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}.
+ * @param value a long or double.
+ * @return a constant pool constant with the given tag and primitive values.
+ */
+ private Symbol addConstantLongOrDouble(final int tag, final long value) {
+ int hashCode = hash(tag, value);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ int index = constantPoolCount;
+ constantPool.putByte(tag).putLong(value);
+ constantPoolCount += 2;
+ return put(new Entry(index, tag, value, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_Long_info or CONSTANT_Double_info to the constant pool of this symbol
+ * table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}.
+ * @param value a long or double.
+ */
+ private void addConstantLongOrDouble(final int index, final int tag, final long value) {
+ add(new Entry(index, tag, value, hash(tag, value)));
+ }
+
+ /**
+ * Adds a CONSTANT_NameAndType_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ * @return a new or already existing Symbol with the given value.
+ */
+ int addConstantNameAndType(final String name, final String descriptor) {
+ final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG;
+ int hashCode = hash(tag, name, descriptor);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag
+ && entry.hashCode == hashCode
+ && entry.name.equals(name)
+ && entry.value.equals(descriptor)) {
+ return entry.index;
+ }
+ entry = entry.next;
+ }
+ constantPool.put122(tag, addConstantUtf8(name), addConstantUtf8(descriptor));
+ return put(new Entry(constantPoolCount++, tag, name, descriptor, hashCode)).index;
+ }
+
+ /**
+ * Adds a new CONSTANT_NameAndType_info to the constant pool of this symbol table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ */
+ private void addConstantNameAndType(final int index, final String name, final String descriptor) {
+ final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG;
+ add(new Entry(index, tag, name, descriptor, hash(tag, name, descriptor)));
+ }
+
+ /**
+ * Adds a CONSTANT_Utf8_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param value a string.
+ * @return a new or already existing Symbol with the given value.
+ */
+ int addConstantUtf8(final String value) {
+ int hashCode = hash(Symbol.CONSTANT_UTF8_TAG, value);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.CONSTANT_UTF8_TAG
+ && entry.hashCode == hashCode
+ && entry.value.equals(value)) {
+ return entry.index;
+ }
+ entry = entry.next;
+ }
+ constantPool.putByte(Symbol.CONSTANT_UTF8_TAG).putUTF8(value);
+ return put(new Entry(constantPoolCount++, Symbol.CONSTANT_UTF8_TAG, value, hashCode)).index;
+ }
+
+ /**
+ * Adds a new CONSTANT_String_info to the constant pool of this symbol table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param value a string.
+ */
+ private void addConstantUtf8(final int index, final String value) {
+ add(new Entry(index, Symbol.CONSTANT_UTF8_TAG, value, hash(Symbol.CONSTANT_UTF8_TAG, value)));
+ }
+
+ /**
+ * Adds a CONSTANT_MethodHandle_info to the constant pool of this symbol table. Does nothing if
+ * the constant pool already contains a similar item.
+ *
+ * @param referenceKind one of {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link
+ * Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link
+ * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link
+ * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of a class of interface.
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ * @param isInterface whether owner is an interface or not.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantMethodHandle(
+ final int referenceKind,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ final int tag = Symbol.CONSTANT_METHOD_HANDLE_TAG;
+ // Note that we don't need to include isInterface in the hash computation, because it is
+ // redundant with owner (we can't have the same owner with different isInterface values).
+ int hashCode = hash(tag, owner, name, descriptor, referenceKind);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag
+ && entry.hashCode == hashCode
+ && entry.data == referenceKind
+ && entry.owner.equals(owner)
+ && entry.name.equals(name)
+ && entry.value.equals(descriptor)) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ if (referenceKind <= Opcodes.H_PUTSTATIC) {
+ constantPool.put112(tag, referenceKind, addConstantFieldref(owner, name, descriptor).index);
+ } else {
+ constantPool.put112(
+ tag, referenceKind, addConstantMethodref(owner, name, descriptor, isInterface).index);
+ }
+ return put(
+ new Entry(constantPoolCount++, tag, owner, name, descriptor, referenceKind, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_MethodHandle_info to the constant pool of this symbol table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param referenceKind one of {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link
+ * Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link
+ * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link
+ * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner the internal name of a class of interface.
+ * @param name a field or method name.
+ * @param descriptor a field or method descriptor.
+ */
+ private void addConstantMethodHandle(
+ final int index,
+ final int referenceKind,
+ final String owner,
+ final String name,
+ final String descriptor) {
+ final int tag = Symbol.CONSTANT_METHOD_HANDLE_TAG;
+ int hashCode = hash(tag, owner, name, descriptor, referenceKind);
+ add(new Entry(index, tag, owner, name, descriptor, referenceKind, hashCode));
+ }
+
+ /**
+ * Adds a CONSTANT_MethodType_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantMethodType(final String methodDescriptor) {
+ return addConstantUtf8Reference(Symbol.CONSTANT_METHOD_TYPE_TAG, methodDescriptor);
+ }
+
+ /**
+ * Adds a CONSTANT_Dynamic_info to the constant pool of this symbol table. Also adds the related
+ * bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the constant
+ * pool already contains a similar item.
+ *
+ * @param name a method name.
+ * @param descriptor a field descriptor.
+ * @param bootstrapMethodHandle a bootstrap method handle.
+ * @param bootstrapMethodArguments the bootstrap method arguments.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments);
+ return addConstantDynamicOrInvokeDynamicReference(
+ Symbol.CONSTANT_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index);
+ }
+
+ /**
+ * Adds a CONSTANT_InvokeDynamic_info to the constant pool of this symbol table. Also adds the
+ * related bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param name a method name.
+ * @param descriptor a method descriptor.
+ * @param bootstrapMethodHandle a bootstrap method handle.
+ * @param bootstrapMethodArguments the bootstrap method arguments.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantInvokeDynamic(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments);
+ return addConstantDynamicOrInvokeDynamicReference(
+ Symbol.CONSTANT_INVOKE_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index);
+ }
+
+ /**
+ * Adds a CONSTANT_Dynamic or a CONSTANT_InvokeDynamic_info to the constant pool of this symbol
+ * table. Does nothing if the constant pool already contains a similar item.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_DYNAMIC_TAG} or {@link
+ * Symbol#CONSTANT_INVOKE_DYNAMIC_TAG}.
+ * @param name a method name.
+ * @param descriptor a field descriptor for CONSTANT_DYNAMIC_TAG) or a method descriptor for
+ * CONSTANT_INVOKE_DYNAMIC_TAG.
+ * @param bootstrapMethodIndex the index of a bootstrap method in the BootstrapMethods attribute.
+ * @return a new or already existing Symbol with the given value.
+ */
+ private Symbol addConstantDynamicOrInvokeDynamicReference(
+ final int tag, final String name, final String descriptor, final int bootstrapMethodIndex) {
+ int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag
+ && entry.hashCode == hashCode
+ && entry.data == bootstrapMethodIndex
+ && entry.name.equals(name)
+ && entry.value.equals(descriptor)) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ constantPool.put122(tag, bootstrapMethodIndex, addConstantNameAndType(name, descriptor));
+ return put(
+ new Entry(
+ constantPoolCount++, tag, null, name, descriptor, bootstrapMethodIndex, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_Dynamic_info or CONSTANT_InvokeDynamic_info to the constant pool of this
+ * symbol table.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_DYNAMIC_TAG} or {@link
+ * Symbol#CONSTANT_INVOKE_DYNAMIC_TAG}.
+ * @param index the constant pool index of the new Symbol.
+ * @param name a method name.
+ * @param descriptor a field descriptor for CONSTANT_DYNAMIC_TAG or a method descriptor for
+ * CONSTANT_INVOKE_DYNAMIC_TAG.
+ * @param bootstrapMethodIndex the index of a bootstrap method in the BootstrapMethods attribute.
+ */
+ private void addConstantDynamicOrInvokeDynamicReference(
+ final int tag,
+ final int index,
+ final String name,
+ final String descriptor,
+ final int bootstrapMethodIndex) {
+ int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex);
+ add(new Entry(index, tag, null, name, descriptor, bootstrapMethodIndex, hashCode));
+ }
+
+ /**
+ * Adds a CONSTANT_Module_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param moduleName a fully qualified name (using dots) of a module.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantModule(final String moduleName) {
+ return addConstantUtf8Reference(Symbol.CONSTANT_MODULE_TAG, moduleName);
+ }
+
+ /**
+ * Adds a CONSTANT_Package_info to the constant pool of this symbol table. Does nothing if the
+ * constant pool already contains a similar item.
+ *
+ * @param packageName the internal name of a package.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addConstantPackage(final String packageName) {
+ return addConstantUtf8Reference(Symbol.CONSTANT_PACKAGE_TAG, packageName);
+ }
+
+ /**
+ * Adds a CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info,
+ * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table. Does
+ * nothing if the constant pool already contains a similar item.
+ *
+ * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link
+ * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link
+ * Symbol#CONSTANT_PACKAGE_TAG}.
+ * @param value an internal class name, an arbitrary string, a method descriptor, a module or a
+ * package name, depending on tag.
+ * @return a new or already existing Symbol with the given value.
+ */
+ private Symbol addConstantUtf8Reference(final int tag, final String value) {
+ int hashCode = hash(tag, value);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == tag && entry.hashCode == hashCode && entry.value.equals(value)) {
+ return entry;
+ }
+ entry = entry.next;
+ }
+ constantPool.put12(tag, addConstantUtf8(value));
+ return put(new Entry(constantPoolCount++, tag, value, hashCode));
+ }
+
+ /**
+ * Adds a new CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info,
+ * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table.
+ *
+ * @param index the constant pool index of the new Symbol.
+ * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link
+ * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link
+ * Symbol#CONSTANT_PACKAGE_TAG}.
+ * @param value an internal class name, an arbitrary string, a method descriptor, a module or a
+ * package name, depending on tag.
+ */
+ private void addConstantUtf8Reference(final int index, final int tag, final String value) {
+ add(new Entry(index, tag, value, hash(tag, value)));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Bootstrap method entries management.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if
+ * the BootstrapMethods already contains a similar bootstrap method.
+ *
+ * @param bootstrapMethodHandle a bootstrap method handle.
+ * @param bootstrapMethodArguments the bootstrap method arguments.
+ * @return a new or already existing Symbol with the given value.
+ */
+ Symbol addBootstrapMethod(
+ final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) {
+ ByteVector bootstrapMethodsAttribute = bootstrapMethods;
+ if (bootstrapMethodsAttribute == null) {
+ bootstrapMethodsAttribute = bootstrapMethods = new ByteVector();
+ }
+
+ // The bootstrap method arguments can be Constant_Dynamic values, which reference other
+ // bootstrap methods. We must therefore add the bootstrap method arguments to the constant pool
+ // and BootstrapMethods attribute first, so that the BootstrapMethods attribute is not modified
+ // while adding the given bootstrap method to it, in the rest of this method.
+ int numBootstrapArguments = bootstrapMethodArguments.length;
+ int[] bootstrapMethodArgumentIndexes = new int[numBootstrapArguments];
+ for (int i = 0; i < numBootstrapArguments; i++) {
+ bootstrapMethodArgumentIndexes[i] = addConstant(bootstrapMethodArguments[i]).index;
+ }
+
+ // Write the bootstrap method in the BootstrapMethods table. This is necessary to be able to
+ // compare it with existing ones, and will be reverted below if there is already a similar
+ // bootstrap method.
+ int bootstrapMethodOffset = bootstrapMethodsAttribute.length;
+ bootstrapMethodsAttribute.putShort(
+ addConstantMethodHandle(
+ bootstrapMethodHandle.getTag(),
+ bootstrapMethodHandle.getOwner(),
+ bootstrapMethodHandle.getName(),
+ bootstrapMethodHandle.getDesc(),
+ bootstrapMethodHandle.isInterface())
+ .index);
+
+ bootstrapMethodsAttribute.putShort(numBootstrapArguments);
+ for (int i = 0; i < numBootstrapArguments; i++) {
+ bootstrapMethodsAttribute.putShort(bootstrapMethodArgumentIndexes[i]);
+ }
+
+ // Compute the length and the hash code of the bootstrap method.
+ int bootstrapMethodlength = bootstrapMethodsAttribute.length - bootstrapMethodOffset;
+ int hashCode = bootstrapMethodHandle.hashCode();
+ for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
+ hashCode ^= bootstrapMethodArgument.hashCode();
+ }
+ hashCode &= 0x7FFFFFFF;
+
+ // Add the bootstrap method to the symbol table or revert the above changes.
+ return addBootstrapMethod(bootstrapMethodOffset, bootstrapMethodlength, hashCode);
+ }
+
+ /**
+ * Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if
+ * the BootstrapMethods already contains a similar bootstrap method (more precisely, reverts the
+ * content of {@link #bootstrapMethods} to remove the last, duplicate bootstrap method).
+ *
+ * @param offset the offset of the last bootstrap method in {@link #bootstrapMethods}, in bytes.
+ * @param length the length of this bootstrap method in {@link #bootstrapMethods}, in bytes.
+ * @param hashCode the hash code of this bootstrap method.
+ * @return a new or already existing Symbol with the given value.
+ */
+ private Symbol addBootstrapMethod(final int offset, final int length, final int hashCode) {
+ final byte[] bootstrapMethodsData = bootstrapMethods.data;
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.BOOTSTRAP_METHOD_TAG && entry.hashCode == hashCode) {
+ int otherOffset = (int) entry.data;
+ boolean isSameBootstrapMethod = true;
+ for (int i = 0; i < length; ++i) {
+ if (bootstrapMethodsData[offset + i] != bootstrapMethodsData[otherOffset + i]) {
+ isSameBootstrapMethod = false;
+ break;
+ }
+ }
+ if (isSameBootstrapMethod) {
+ bootstrapMethods.length = offset; // Revert to old position.
+ return entry;
+ }
+ }
+ entry = entry.next;
+ }
+ return put(new Entry(bootstrapMethodCount++, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Type table entries management.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the type table element whose index is given.
+ *
+ * @param typeIndex a type table index.
+ * @return the type table element whose index is given.
+ */
+ Symbol getType(final int typeIndex) {
+ return typeTable[typeIndex];
+ }
+
+ /**
+ * Adds a type in the type table of this symbol table. Does nothing if the type table already
+ * contains a similar type.
+ *
+ * @param value an internal class name.
+ * @return the index of a new or already existing type Symbol with the given value.
+ */
+ int addType(final String value) {
+ int hashCode = hash(Symbol.TYPE_TAG, value);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.TYPE_TAG && entry.hashCode == hashCode && entry.value.equals(value)) {
+ return entry.index;
+ }
+ entry = entry.next;
+ }
+ return addTypeInternal(new Entry(typeCount, Symbol.TYPE_TAG, value, hashCode));
+ }
+
+ /**
+ * Adds an {@link Frame#ITEM_UNINITIALIZED} type in the type table of this symbol table. Does
+ * nothing if the type table already contains a similar type.
+ *
+ * @param value an internal class name.
+ * @param bytecodeOffset the bytecode offset of the NEW instruction that created this {@link
+ * Frame#ITEM_UNINITIALIZED} type value.
+ * @return the index of a new or already existing type Symbol with the given value.
+ */
+ int addUninitializedType(final String value, final int bytecodeOffset) {
+ int hashCode = hash(Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.UNINITIALIZED_TYPE_TAG
+ && entry.hashCode == hashCode
+ && entry.data == bytecodeOffset
+ && entry.value.equals(value)) {
+ return entry.index;
+ }
+ entry = entry.next;
+ }
+ return addTypeInternal(
+ new Entry(typeCount, Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset, hashCode));
+ }
+
+ /**
+ * Adds a merged type in the type table of this symbol table. Does nothing if the type table
+ * already contains a similar type.
+ *
+ * @param typeTableIndex1 a {@link Symbol#TYPE_TAG} type, specified by its index in the type
+ * table.
+ * @param typeTableIndex2 another {@link Symbol#TYPE_TAG} type, specified by its index in the type
+ * table.
+ * @return the index of a new or already existing {@link Symbol#TYPE_TAG} type Symbol,
+ * corresponding to the common super class of the given types.
+ */
+ int addMergedType(final int typeTableIndex1, final int typeTableIndex2) {
+ long data =
+ typeTableIndex1 < typeTableIndex2
+ ? typeTableIndex1 | (((long) typeTableIndex2) << 32)
+ : typeTableIndex2 | (((long) typeTableIndex1) << 32);
+ int hashCode = hash(Symbol.MERGED_TYPE_TAG, typeTableIndex1 + typeTableIndex2);
+ Entry entry = get(hashCode);
+ while (entry != null) {
+ if (entry.tag == Symbol.MERGED_TYPE_TAG && entry.hashCode == hashCode && entry.data == data) {
+ return entry.info;
+ }
+ entry = entry.next;
+ }
+ String type1 = typeTable[typeTableIndex1].value;
+ String type2 = typeTable[typeTableIndex2].value;
+ int commonSuperTypeIndex = addType(classWriter.getCommonSuperClass(type1, type2));
+ put(new Entry(typeCount, Symbol.MERGED_TYPE_TAG, data, hashCode)).info = commonSuperTypeIndex;
+ return commonSuperTypeIndex;
+ }
+
+ /**
+ * Adds the given type Symbol to {@link #typeTable}.
+ *
+ * @param entry a {@link Symbol#TYPE_TAG} or {@link Symbol#UNINITIALIZED_TYPE_TAG} type symbol.
+ * The index of this Symbol must be equal to the current value of {@link #typeCount}.
+ * @return the index in {@link #typeTable} where the given type was added, which is also equal to
+ * entry's index by hypothesis.
+ */
+ private int addTypeInternal(final Entry entry) {
+ if (typeTable == null) {
+ typeTable = new Entry[16];
+ }
+ if (typeCount == typeTable.length) {
+ Entry[] newTypeTable = new Entry[2 * typeTable.length];
+ System.arraycopy(typeTable, 0, newTypeTable, 0, typeTable.length);
+ typeTable = newTypeTable;
+ }
+ typeTable[typeCount++] = entry;
+ return put(entry).index;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Static helper methods to compute hash codes.
+ // -----------------------------------------------------------------------------------------------
+
+ private static int hash(final int tag, final int value) {
+ return 0x7FFFFFFF & (tag + value);
+ }
+
+ private static int hash(final int tag, final long value) {
+ return 0x7FFFFFFF & (tag + (int) value + (int) (value >>> 32));
+ }
+
+ private static int hash(final int tag, final String value) {
+ return 0x7FFFFFFF & (tag + value.hashCode());
+ }
+
+ private static int hash(final int tag, final String value1, final int value2) {
+ return 0x7FFFFFFF & (tag + value1.hashCode() + value2);
+ }
+
+ private static int hash(final int tag, final String value1, final String value2) {
+ return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode());
+ }
+
+ private static int hash(
+ final int tag, final String value1, final String value2, final int value3) {
+ return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * (value3 + 1));
+ }
+
+ private static int hash(
+ final int tag, final String value1, final String value2, final String value3) {
+ return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * value3.hashCode());
+ }
+
+ private static int hash(
+ final int tag,
+ final String value1,
+ final String value2,
+ final String value3,
+ final int value4) {
+ return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * value3.hashCode() * value4);
+ }
+
+ /**
+ * An entry of a SymbolTable. This concrete and private subclass of {@link Symbol} adds two fields
+ * which are only used inside SymbolTable, to implement hash sets of symbols (in order to avoid
+ * duplicate symbols). See {@link #entries}.
+ *
+ * @author Eric Bruneton
+ */
+ private static class Entry extends Symbol {
+
+ /** The hash code of this entry. */
+ final int hashCode;
+
+ /**
+ * Another entry (and so on recursively) having the same hash code (modulo the size of {@link
+ * #entries}) as this one.
+ */
+ Entry next;
+
+ Entry(
+ final int index,
+ final int tag,
+ final String owner,
+ final String name,
+ final String value,
+ final long data,
+ final int hashCode) {
+ super(index, tag, owner, name, value, data);
+ this.hashCode = hashCode;
+ }
+
+ Entry(final int index, final int tag, final String value, final int hashCode) {
+ super(index, tag, /* owner = */ null, /* name = */ null, value, /* data = */ 0);
+ this.hashCode = hashCode;
+ }
+
+ Entry(final int index, final int tag, final String value, final long data, final int hashCode) {
+ super(index, tag, /* owner = */ null, /* name = */ null, value, data);
+ this.hashCode = hashCode;
+ }
+
+ Entry(
+ final int index, final int tag, final String name, final String value, final int hashCode) {
+ super(index, tag, /* owner = */ null, name, value, /* data = */ 0);
+ this.hashCode = hashCode;
+ }
+
+ Entry(final int index, final int tag, final long data, final int hashCode) {
+ super(index, tag, /* owner = */ null, /* name = */ null, /* value = */ null, data);
+ this.hashCode = hashCode;
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/Type.java b/asm/src/main/java/org/objectweb/asm/Type.java
new file mode 100644
index 00000000..85aab7ea
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/Type.java
@@ -0,0 +1,895 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * A Java field or method type. This class can be used to make it easier to manipulate type and
+ * method descriptors.
+ *
+ * @author Eric Bruneton
+ * @author Chris Nokleberg
+ */
+public final class Type {
+
+ /** The sort of the {@code void} type. See {@link #getSort}. */
+ public static final int VOID = 0;
+
+ /** The sort of the {@code boolean} type. See {@link #getSort}. */
+ public static final int BOOLEAN = 1;
+
+ /** The sort of the {@code char} type. See {@link #getSort}. */
+ public static final int CHAR = 2;
+
+ /** The sort of the {@code byte} type. See {@link #getSort}. */
+ public static final int BYTE = 3;
+
+ /** The sort of the {@code short} type. See {@link #getSort}. */
+ public static final int SHORT = 4;
+
+ /** The sort of the {@code int} type. See {@link #getSort}. */
+ public static final int INT = 5;
+
+ /** The sort of the {@code float} type. See {@link #getSort}. */
+ public static final int FLOAT = 6;
+
+ /** The sort of the {@code long} type. See {@link #getSort}. */
+ public static final int LONG = 7;
+
+ /** The sort of the {@code double} type. See {@link #getSort}. */
+ public static final int DOUBLE = 8;
+
+ /** The sort of array reference types. See {@link #getSort}. */
+ public static final int ARRAY = 9;
+
+ /** The sort of object reference types. See {@link #getSort}. */
+ public static final int OBJECT = 10;
+
+ /** The sort of method types. See {@link #getSort}. */
+ public static final int METHOD = 11;
+
+ /** The (private) sort of object reference types represented with an internal name. */
+ private static final int INTERNAL = 12;
+
+ /** The descriptors of the primitive types. */
+ private static final String PRIMITIVE_DESCRIPTORS = "VZCBSIFJD";
+
+ /** The {@code void} type. */
+ public static final Type VOID_TYPE = new Type(VOID, PRIMITIVE_DESCRIPTORS, VOID, VOID + 1);
+
+ /** The {@code boolean} type. */
+ public static final Type BOOLEAN_TYPE =
+ new Type(BOOLEAN, PRIMITIVE_DESCRIPTORS, BOOLEAN, BOOLEAN + 1);
+
+ /** The {@code char} type. */
+ public static final Type CHAR_TYPE = new Type(CHAR, PRIMITIVE_DESCRIPTORS, CHAR, CHAR + 1);
+
+ /** The {@code byte} type. */
+ public static final Type BYTE_TYPE = new Type(BYTE, PRIMITIVE_DESCRIPTORS, BYTE, BYTE + 1);
+
+ /** The {@code short} type. */
+ public static final Type SHORT_TYPE = new Type(SHORT, PRIMITIVE_DESCRIPTORS, SHORT, SHORT + 1);
+
+ /** The {@code int} type. */
+ public static final Type INT_TYPE = new Type(INT, PRIMITIVE_DESCRIPTORS, INT, INT + 1);
+
+ /** The {@code float} type. */
+ public static final Type FLOAT_TYPE = new Type(FLOAT, PRIMITIVE_DESCRIPTORS, FLOAT, FLOAT + 1);
+
+ /** The {@code long} type. */
+ public static final Type LONG_TYPE = new Type(LONG, PRIMITIVE_DESCRIPTORS, LONG, LONG + 1);
+
+ /** The {@code double} type. */
+ public static final Type DOUBLE_TYPE =
+ new Type(DOUBLE, PRIMITIVE_DESCRIPTORS, DOUBLE, DOUBLE + 1);
+
+ // -----------------------------------------------------------------------------------------------
+ // Fields
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * The sort of this type. Either {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE},
+ * {@link #SHORT}, {@link #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY},
+ * {@link #OBJECT}, {@link #METHOD} or {@link #INTERNAL}.
+ */
+ private final int sort;
+
+ /**
+ * A buffer containing the value of this field or method type. This value is an internal name for
+ * {@link #OBJECT} and {@link #INTERNAL} types, and a field or method descriptor in the other
+ * cases.
+ *
+ * <p>For {@link #OBJECT} types, this field also contains the descriptor: the characters in
+ * [{@link #valueBegin},{@link #valueEnd}) contain the internal name, and those in [{@link
+ * #valueBegin} - 1, {@link #valueEnd} + 1) contain the descriptor.
+ */
+ private final String valueBuffer;
+
+ /**
+ * The beginning index, inclusive, of the value of this Java field or method type in {@link
+ * #valueBuffer}. This value is an internal name for {@link #OBJECT} and {@link #INTERNAL} types,
+ * and a field or method descriptor in the other cases.
+ */
+ private final int valueBegin;
+
+ /**
+ * The end index, exclusive, of the value of this Java field or method type in {@link
+ * #valueBuffer}. This value is an internal name for {@link #OBJECT} and {@link #INTERNAL} types,
+ * and a field or method descriptor in the other cases.
+ */
+ private final int valueEnd;
+
+ /**
+ * Constructs a reference type.
+ *
+ * @param sort the sort of this type, see {@link #sort}.
+ * @param valueBuffer a buffer containing the value of this field or method type.
+ * @param valueBegin the beginning index, inclusive, of the value of this field or method type in
+ * valueBuffer.
+ * @param valueEnd the end index, exclusive, of the value of this field or method type in
+ * valueBuffer.
+ */
+ private Type(final int sort, final String valueBuffer, final int valueBegin, final int valueEnd) {
+ this.sort = sort;
+ this.valueBuffer = valueBuffer;
+ this.valueBegin = valueBegin;
+ this.valueEnd = valueEnd;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to get Type(s) from a descriptor, a reflected Method or Constructor, other types, etc.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the {@link Type} corresponding to the given type descriptor.
+ *
+ * @param typeDescriptor a field or method type descriptor.
+ * @return the {@link Type} corresponding to the given type descriptor.
+ */
+ public static Type getType(final String typeDescriptor) {
+ return getTypeInternal(typeDescriptor, 0, typeDescriptor.length());
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the given class.
+ *
+ * @param clazz a class.
+ * @return the {@link Type} corresponding to the given class.
+ */
+ public static Type getType(final Class<?> clazz) {
+ if (clazz.isPrimitive()) {
+ if (clazz == Integer.TYPE) {
+ return INT_TYPE;
+ } else if (clazz == Void.TYPE) {
+ return VOID_TYPE;
+ } else if (clazz == Boolean.TYPE) {
+ return BOOLEAN_TYPE;
+ } else if (clazz == Byte.TYPE) {
+ return BYTE_TYPE;
+ } else if (clazz == Character.TYPE) {
+ return CHAR_TYPE;
+ } else if (clazz == Short.TYPE) {
+ return SHORT_TYPE;
+ } else if (clazz == Double.TYPE) {
+ return DOUBLE_TYPE;
+ } else if (clazz == Float.TYPE) {
+ return FLOAT_TYPE;
+ } else if (clazz == Long.TYPE) {
+ return LONG_TYPE;
+ } else {
+ throw new AssertionError();
+ }
+ } else {
+ return getType(getDescriptor(clazz));
+ }
+ }
+
+ /**
+ * Returns the method {@link Type} corresponding to the given constructor.
+ *
+ * @param constructor a {@link Constructor} object.
+ * @return the method {@link Type} corresponding to the given constructor.
+ */
+ public static Type getType(final Constructor<?> constructor) {
+ return getType(getConstructorDescriptor(constructor));
+ }
+
+ /**
+ * Returns the method {@link Type} corresponding to the given method.
+ *
+ * @param method a {@link Method} object.
+ * @return the method {@link Type} corresponding to the given method.
+ */
+ public static Type getType(final Method method) {
+ return getType(getMethodDescriptor(method));
+ }
+
+ /**
+ * Returns the type of the elements of this array type. This method should only be used for an
+ * array type.
+ *
+ * @return Returns the type of the elements of this array type.
+ */
+ public Type getElementType() {
+ final int numDimensions = getDimensions();
+ return getTypeInternal(valueBuffer, valueBegin + numDimensions, valueEnd);
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the given internal name.
+ *
+ * @param internalName an internal name (see {@link Type#getInternalName()}).
+ * @return the {@link Type} corresponding to the given internal name.
+ */
+ public static Type getObjectType(final String internalName) {
+ return new Type(
+ internalName.charAt(0) == '[' ? ARRAY : INTERNAL, internalName, 0, internalName.length());
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the given method descriptor. Equivalent to <code>
+ * Type.getType(methodDescriptor)</code>.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the {@link Type} corresponding to the given method descriptor.
+ */
+ public static Type getMethodType(final String methodDescriptor) {
+ return new Type(METHOD, methodDescriptor, 0, methodDescriptor.length());
+ }
+
+ /**
+ * Returns the method {@link Type} corresponding to the given argument and return types.
+ *
+ * @param returnType the return type of the method.
+ * @param argumentTypes the argument types of the method.
+ * @return the method {@link Type} corresponding to the given argument and return types.
+ */
+ public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
+ return getType(getMethodDescriptor(returnType, argumentTypes));
+ }
+
+ /**
+ * Returns the argument types of methods of this type. This method should only be used for method
+ * types.
+ *
+ * @return the argument types of methods of this type.
+ */
+ public Type[] getArgumentTypes() {
+ return getArgumentTypes(getDescriptor());
+ }
+
+ /**
+ * Returns the {@link Type} values corresponding to the argument types of the given method
+ * descriptor.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the {@link Type} values corresponding to the argument types of the given method
+ * descriptor.
+ */
+ public static Type[] getArgumentTypes(final String methodDescriptor) {
+ // First step: compute the number of argument types in methodDescriptor.
+ int numArgumentTypes = 0;
+ // Skip the first character, which is always a '('.
+ int currentOffset = 1;
+ // Parse the argument types, one at a each loop iteration.
+ while (methodDescriptor.charAt(currentOffset) != ')') {
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ ++numArgumentTypes;
+ }
+
+ // Second step: create a Type instance for each argument type.
+ Type[] argumentTypes = new Type[numArgumentTypes];
+ // Skip the first character, which is always a '('.
+ currentOffset = 1;
+ // Parse and create the argument types, one at each loop iteration.
+ int currentArgumentTypeIndex = 0;
+ while (methodDescriptor.charAt(currentOffset) != ')') {
+ final int currentArgumentTypeOffset = currentOffset;
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ argumentTypes[currentArgumentTypeIndex++] =
+ getTypeInternal(methodDescriptor, currentArgumentTypeOffset, currentOffset);
+ }
+ return argumentTypes;
+ }
+
+ /**
+ * Returns the {@link Type} values corresponding to the argument types of the given method.
+ *
+ * @param method a method.
+ * @return the {@link Type} values corresponding to the argument types of the given method.
+ */
+ public static Type[] getArgumentTypes(final Method method) {
+ Class<?>[] classes = method.getParameterTypes();
+ Type[] types = new Type[classes.length];
+ for (int i = classes.length - 1; i >= 0; --i) {
+ types[i] = getType(classes[i]);
+ }
+ return types;
+ }
+
+ /**
+ * Returns the return type of methods of this type. This method should only be used for method
+ * types.
+ *
+ * @return the return type of methods of this type.
+ */
+ public Type getReturnType() {
+ return getReturnType(getDescriptor());
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the return type of the given method descriptor.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the {@link Type} corresponding to the return type of the given method descriptor.
+ */
+ public static Type getReturnType(final String methodDescriptor) {
+ return getTypeInternal(
+ methodDescriptor, getReturnTypeOffset(methodDescriptor), methodDescriptor.length());
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the return type of the given method.
+ *
+ * @param method a method.
+ * @return the {@link Type} corresponding to the return type of the given method.
+ */
+ public static Type getReturnType(final Method method) {
+ return getType(method.getReturnType());
+ }
+
+ /**
+ * Returns the start index of the return type of the given method descriptor.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the start index of the return type of the given method descriptor.
+ */
+ static int getReturnTypeOffset(final String methodDescriptor) {
+ // Skip the first character, which is always a '('.
+ int currentOffset = 1;
+ // Skip the argument types, one at a each loop iteration.
+ while (methodDescriptor.charAt(currentOffset) != ')') {
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ }
+ return currentOffset + 1;
+ }
+
+ /**
+ * Returns the {@link Type} corresponding to the given field or method descriptor.
+ *
+ * @param descriptorBuffer a buffer containing the field or method descriptor.
+ * @param descriptorBegin the beginning index, inclusive, of the field or method descriptor in
+ * descriptorBuffer.
+ * @param descriptorEnd the end index, exclusive, of the field or method descriptor in
+ * descriptorBuffer.
+ * @return the {@link Type} corresponding to the given type descriptor.
+ */
+ private static Type getTypeInternal(
+ final String descriptorBuffer, final int descriptorBegin, final int descriptorEnd) {
+ switch (descriptorBuffer.charAt(descriptorBegin)) {
+ case 'V':
+ return VOID_TYPE;
+ case 'Z':
+ return BOOLEAN_TYPE;
+ case 'C':
+ return CHAR_TYPE;
+ case 'B':
+ return BYTE_TYPE;
+ case 'S':
+ return SHORT_TYPE;
+ case 'I':
+ return INT_TYPE;
+ case 'F':
+ return FLOAT_TYPE;
+ case 'J':
+ return LONG_TYPE;
+ case 'D':
+ return DOUBLE_TYPE;
+ case '[':
+ return new Type(ARRAY, descriptorBuffer, descriptorBegin, descriptorEnd);
+ case 'L':
+ return new Type(OBJECT, descriptorBuffer, descriptorBegin + 1, descriptorEnd - 1);
+ case '(':
+ return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
+ default:
+ throw new IllegalArgumentException("Invalid descriptor: " + descriptorBuffer);
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to get class names, internal names or descriptors.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the binary name of the class corresponding to this type. This method must not be used
+ * on method types.
+ *
+ * @return the binary name of the class corresponding to this type.
+ */
+ public String getClassName() {
+ switch (sort) {
+ case VOID:
+ return "void";
+ case BOOLEAN:
+ return "boolean";
+ case CHAR:
+ return "char";
+ case BYTE:
+ return "byte";
+ case SHORT:
+ return "short";
+ case INT:
+ return "int";
+ case FLOAT:
+ return "float";
+ case LONG:
+ return "long";
+ case DOUBLE:
+ return "double";
+ case ARRAY:
+ StringBuilder stringBuilder = new StringBuilder(getElementType().getClassName());
+ for (int i = getDimensions(); i > 0; --i) {
+ stringBuilder.append("[]");
+ }
+ return stringBuilder.toString();
+ case OBJECT:
+ case INTERNAL:
+ return valueBuffer.substring(valueBegin, valueEnd).replace('/', '.');
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Returns the internal name of the class corresponding to this object or array type. The internal
+ * name of a class is its fully qualified name (as returned by Class.getName(), where '.' are
+ * replaced by '/'). This method should only be used for an object or array type.
+ *
+ * @return the internal name of the class corresponding to this object type.
+ */
+ public String getInternalName() {
+ return valueBuffer.substring(valueBegin, valueEnd);
+ }
+
+ /**
+ * Returns the internal name of the given class. The internal name of a class is its fully
+ * qualified name, as returned by Class.getName(), where '.' are replaced by '/'.
+ *
+ * @param clazz an object or array class.
+ * @return the internal name of the given class.
+ */
+ public static String getInternalName(final Class<?> clazz) {
+ return clazz.getName().replace('.', '/');
+ }
+
+ /**
+ * Returns the descriptor corresponding to this type.
+ *
+ * @return the descriptor corresponding to this type.
+ */
+ public String getDescriptor() {
+ if (sort == OBJECT) {
+ return valueBuffer.substring(valueBegin - 1, valueEnd + 1);
+ } else if (sort == INTERNAL) {
+ return 'L' + valueBuffer.substring(valueBegin, valueEnd) + ';';
+ } else {
+ return valueBuffer.substring(valueBegin, valueEnd);
+ }
+ }
+
+ /**
+ * Returns the descriptor corresponding to the given class.
+ *
+ * @param clazz an object class, a primitive class or an array class.
+ * @return the descriptor corresponding to the given class.
+ */
+ public static String getDescriptor(final Class<?> clazz) {
+ StringBuilder stringBuilder = new StringBuilder();
+ appendDescriptor(clazz, stringBuilder);
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Returns the descriptor corresponding to the given constructor.
+ *
+ * @param constructor a {@link Constructor} object.
+ * @return the descriptor of the given constructor.
+ */
+ public static String getConstructorDescriptor(final Constructor<?> constructor) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append('(');
+ Class<?>[] parameters = constructor.getParameterTypes();
+ for (Class<?> parameter : parameters) {
+ appendDescriptor(parameter, stringBuilder);
+ }
+ return stringBuilder.append(")V").toString();
+ }
+
+ /**
+ * Returns the descriptor corresponding to the given argument and return types.
+ *
+ * @param returnType the return type of the method.
+ * @param argumentTypes the argument types of the method.
+ * @return the descriptor corresponding to the given argument and return types.
+ */
+ public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append('(');
+ for (Type argumentType : argumentTypes) {
+ argumentType.appendDescriptor(stringBuilder);
+ }
+ stringBuilder.append(')');
+ returnType.appendDescriptor(stringBuilder);
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Returns the descriptor corresponding to the given method.
+ *
+ * @param method a {@link Method} object.
+ * @return the descriptor of the given method.
+ */
+ public static String getMethodDescriptor(final Method method) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append('(');
+ Class<?>[] parameters = method.getParameterTypes();
+ for (Class<?> parameter : parameters) {
+ appendDescriptor(parameter, stringBuilder);
+ }
+ stringBuilder.append(')');
+ appendDescriptor(method.getReturnType(), stringBuilder);
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Appends the descriptor corresponding to this type to the given string buffer.
+ *
+ * @param stringBuilder the string builder to which the descriptor must be appended.
+ */
+ private void appendDescriptor(final StringBuilder stringBuilder) {
+ if (sort == OBJECT) {
+ stringBuilder.append(valueBuffer, valueBegin - 1, valueEnd + 1);
+ } else if (sort == INTERNAL) {
+ stringBuilder.append('L').append(valueBuffer, valueBegin, valueEnd).append(';');
+ } else {
+ stringBuilder.append(valueBuffer, valueBegin, valueEnd);
+ }
+ }
+
+ /**
+ * Appends the descriptor of the given class to the given string builder.
+ *
+ * @param clazz the class whose descriptor must be computed.
+ * @param stringBuilder the string builder to which the descriptor must be appended.
+ */
+ private static void appendDescriptor(final Class<?> clazz, final StringBuilder stringBuilder) {
+ Class<?> currentClass = clazz;
+ while (currentClass.isArray()) {
+ stringBuilder.append('[');
+ currentClass = currentClass.getComponentType();
+ }
+ if (currentClass.isPrimitive()) {
+ char descriptor;
+ if (currentClass == Integer.TYPE) {
+ descriptor = 'I';
+ } else if (currentClass == Void.TYPE) {
+ descriptor = 'V';
+ } else if (currentClass == Boolean.TYPE) {
+ descriptor = 'Z';
+ } else if (currentClass == Byte.TYPE) {
+ descriptor = 'B';
+ } else if (currentClass == Character.TYPE) {
+ descriptor = 'C';
+ } else if (currentClass == Short.TYPE) {
+ descriptor = 'S';
+ } else if (currentClass == Double.TYPE) {
+ descriptor = 'D';
+ } else if (currentClass == Float.TYPE) {
+ descriptor = 'F';
+ } else if (currentClass == Long.TYPE) {
+ descriptor = 'J';
+ } else {
+ throw new AssertionError();
+ }
+ stringBuilder.append(descriptor);
+ } else {
+ stringBuilder.append('L').append(getInternalName(currentClass)).append(';');
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Methods to get the sort, dimension, size, and opcodes corresponding to a Type or descriptor.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the sort of this type.
+ *
+ * @return {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE}, {@link #SHORT}, {@link
+ * #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY}, {@link #OBJECT} or
+ * {@link #METHOD}.
+ */
+ public int getSort() {
+ return sort == INTERNAL ? OBJECT : sort;
+ }
+
+ /**
+ * Returns the number of dimensions of this array type. This method should only be used for an
+ * array type.
+ *
+ * @return the number of dimensions of this array type.
+ */
+ public int getDimensions() {
+ int numDimensions = 1;
+ while (valueBuffer.charAt(valueBegin + numDimensions) == '[') {
+ numDimensions++;
+ }
+ return numDimensions;
+ }
+
+ /**
+ * Returns the size of values of this type. This method must not be used for method types.
+ *
+ * @return the size of values of this type, i.e., 2 for {@code long} and {@code double}, 0 for
+ * {@code void} and 1 otherwise.
+ */
+ public int getSize() {
+ switch (sort) {
+ case VOID:
+ return 0;
+ case BOOLEAN:
+ case CHAR:
+ case BYTE:
+ case SHORT:
+ case INT:
+ case FLOAT:
+ case ARRAY:
+ case OBJECT:
+ case INTERNAL:
+ return 1;
+ case LONG:
+ case DOUBLE:
+ return 2;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Returns the size of the arguments and of the return value of methods of this type. This method
+ * should only be used for method types.
+ *
+ * @return the size of the arguments of the method (plus one for the implicit this argument),
+ * argumentsSize, and the size of its return value, returnSize, packed into a single int i =
+ * {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
+ * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
+ */
+ public int getArgumentsAndReturnSizes() {
+ return getArgumentsAndReturnSizes(getDescriptor());
+ }
+
+ /**
+ * Computes the size of the arguments and of the return value of a method.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the size of the arguments of the method (plus one for the implicit this argument),
+ * argumentsSize, and the size of its return value, returnSize, packed into a single int i =
+ * {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
+ * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
+ */
+ public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
+ int argumentsSize = 1;
+ // Skip the first character, which is always a '('.
+ int currentOffset = 1;
+ int currentChar = methodDescriptor.charAt(currentOffset);
+ // Parse the argument types and compute their size, one at a each loop iteration.
+ while (currentChar != ')') {
+ if (currentChar == 'J' || currentChar == 'D') {
+ currentOffset++;
+ argumentsSize += 2;
+ } else {
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ argumentsSize += 1;
+ }
+ currentChar = methodDescriptor.charAt(currentOffset);
+ }
+ currentChar = methodDescriptor.charAt(currentOffset + 1);
+ if (currentChar == 'V') {
+ return argumentsSize << 2;
+ } else {
+ int returnSize = (currentChar == 'J' || currentChar == 'D') ? 2 : 1;
+ return argumentsSize << 2 | returnSize;
+ }
+ }
+
+ /**
+ * Returns a JVM instruction opcode adapted to this {@link Type}. This method must not be used for
+ * method types.
+ *
+ * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD,
+ * IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and
+ * IRETURN.
+ * @return an opcode that is similar to the given opcode, but adapted to this {@link Type}. For
+ * example, if this type is {@code float} and {@code opcode} is IRETURN, this method returns
+ * FRETURN.
+ */
+ public int getOpcode(final int opcode) {
+ if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
+ switch (sort) {
+ case BOOLEAN:
+ case BYTE:
+ return opcode + (Opcodes.BALOAD - Opcodes.IALOAD);
+ case CHAR:
+ return opcode + (Opcodes.CALOAD - Opcodes.IALOAD);
+ case SHORT:
+ return opcode + (Opcodes.SALOAD - Opcodes.IALOAD);
+ case INT:
+ return opcode;
+ case FLOAT:
+ return opcode + (Opcodes.FALOAD - Opcodes.IALOAD);
+ case LONG:
+ return opcode + (Opcodes.LALOAD - Opcodes.IALOAD);
+ case DOUBLE:
+ return opcode + (Opcodes.DALOAD - Opcodes.IALOAD);
+ case ARRAY:
+ case OBJECT:
+ case INTERNAL:
+ return opcode + (Opcodes.AALOAD - Opcodes.IALOAD);
+ case METHOD:
+ case VOID:
+ throw new UnsupportedOperationException();
+ default:
+ throw new AssertionError();
+ }
+ } else {
+ switch (sort) {
+ case VOID:
+ if (opcode != Opcodes.IRETURN) {
+ throw new UnsupportedOperationException();
+ }
+ return Opcodes.RETURN;
+ case BOOLEAN:
+ case BYTE:
+ case CHAR:
+ case SHORT:
+ case INT:
+ return opcode;
+ case FLOAT:
+ return opcode + (Opcodes.FRETURN - Opcodes.IRETURN);
+ case LONG:
+ return opcode + (Opcodes.LRETURN - Opcodes.IRETURN);
+ case DOUBLE:
+ return opcode + (Opcodes.DRETURN - Opcodes.IRETURN);
+ case ARRAY:
+ case OBJECT:
+ case INTERNAL:
+ if (opcode != Opcodes.ILOAD && opcode != Opcodes.ISTORE && opcode != Opcodes.IRETURN) {
+ throw new UnsupportedOperationException();
+ }
+ return opcode + (Opcodes.ARETURN - Opcodes.IRETURN);
+ case METHOD:
+ throw new UnsupportedOperationException();
+ default:
+ throw new AssertionError();
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Equals, hashCode and toString.
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Tests if the given object is equal to this type.
+ *
+ * @param object the object to be compared to this type.
+ * @return {@literal true} if the given object is equal to this type.
+ */
+ @Override
+ public boolean equals(final Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof Type)) {
+ return false;
+ }
+ Type other = (Type) object;
+ if ((sort == INTERNAL ? OBJECT : sort) != (other.sort == INTERNAL ? OBJECT : other.sort)) {
+ return false;
+ }
+ int begin = valueBegin;
+ int end = valueEnd;
+ int otherBegin = other.valueBegin;
+ int otherEnd = other.valueEnd;
+ // Compare the values.
+ if (end - begin != otherEnd - otherBegin) {
+ return false;
+ }
+ for (int i = begin, j = otherBegin; i < end; i++, j++) {
+ if (valueBuffer.charAt(i) != other.valueBuffer.charAt(j)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a hash code value for this type.
+ *
+ * @return a hash code value for this type.
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 13 * (sort == INTERNAL ? OBJECT : sort);
+ if (sort >= ARRAY) {
+ for (int i = valueBegin, end = valueEnd; i < end; i++) {
+ hashCode = 17 * (hashCode + valueBuffer.charAt(i));
+ }
+ }
+ return hashCode;
+ }
+
+ /**
+ * Returns a string representation of this type.
+ *
+ * @return the descriptor of this type.
+ */
+ @Override
+ public String toString() {
+ return getDescriptor();
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/TypePath.java b/asm/src/main/java/org/objectweb/asm/TypePath.java
new file mode 100644
index 00000000..7d6217e6
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/TypePath.java
@@ -0,0 +1,201 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm;
+
+/**
+ * The path to a type argument, wildcard bound, array element type, or static inner type within an
+ * enclosing type.
+ *
+ * @author Eric Bruneton
+ */
+public final class TypePath {
+
+ /** A type path step that steps into the element type of an array type. See {@link #getStep}. */
+ public static final int ARRAY_ELEMENT = 0;
+
+ /** A type path step that steps into the nested type of a class type. See {@link #getStep}. */
+ public static final int INNER_TYPE = 1;
+
+ /** A type path step that steps into the bound of a wildcard type. See {@link #getStep}. */
+ public static final int WILDCARD_BOUND = 2;
+
+ /** A type path step that steps into a type argument of a generic type. See {@link #getStep}. */
+ public static final int TYPE_ARGUMENT = 3;
+
+ /**
+ * The byte array where the 'type_path' structure - as defined in the Java Virtual Machine
+ * Specification (JVMS) - corresponding to this TypePath is stored. The first byte of the
+ * structure in this array is given by {@link #typePathOffset}.
+ *
+ * @see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.2">JVMS
+ * 4.7.20.2</a>
+ */
+ private final byte[] typePathContainer;
+
+ /** The offset of the first byte of the type_path JVMS structure in {@link #typePathContainer}. */
+ private final int typePathOffset;
+
+ /**
+ * Constructs a new TypePath.
+ *
+ * @param typePathContainer a byte array containing a type_path JVMS structure.
+ * @param typePathOffset the offset of the first byte of the type_path structure in
+ * typePathContainer.
+ */
+ TypePath(final byte[] typePathContainer, final int typePathOffset) {
+ this.typePathContainer = typePathContainer;
+ this.typePathOffset = typePathOffset;
+ }
+
+ /**
+ * Returns the length of this path, i.e. its number of steps.
+ *
+ * @return the length of this path.
+ */
+ public int getLength() {
+ // path_length is stored in the first byte of a type_path.
+ return typePathContainer[typePathOffset];
+ }
+
+ /**
+ * Returns the value of the given step of this path.
+ *
+ * @param index an index between 0 and {@link #getLength()}, exclusive.
+ * @return one of {@link #ARRAY_ELEMENT}, {@link #INNER_TYPE}, {@link #WILDCARD_BOUND}, or {@link
+ * #TYPE_ARGUMENT}.
+ */
+ public int getStep(final int index) {
+ // Returns the type_path_kind of the path element of the given index.
+ return typePathContainer[typePathOffset + 2 * index + 1];
+ }
+
+ /**
+ * Returns the index of the type argument that the given step is stepping into. This method should
+ * only be used for steps whose value is {@link #TYPE_ARGUMENT}.
+ *
+ * @param index an index between 0 and {@link #getLength()}, exclusive.
+ * @return the index of the type argument that the given step is stepping into.
+ */
+ public int getStepArgument(final int index) {
+ // Returns the type_argument_index of the path element of the given index.
+ return typePathContainer[typePathOffset + 2 * index + 2];
+ }
+
+ /**
+ * Converts a type path in string form, in the format used by {@link #toString()}, into a TypePath
+ * object.
+ *
+ * @param typePath a type path in string form, in the format used by {@link #toString()}. May be
+ * {@literal null} or empty.
+ * @return the corresponding TypePath object, or {@literal null} if the path is empty.
+ */
+ public static TypePath fromString(final String typePath) {
+ if (typePath == null || typePath.length() == 0) {
+ return null;
+ }
+ int typePathLength = typePath.length();
+ ByteVector output = new ByteVector(typePathLength);
+ output.putByte(0);
+ int typePathIndex = 0;
+ while (typePathIndex < typePathLength) {
+ char c = typePath.charAt(typePathIndex++);
+ if (c == '[') {
+ output.put11(ARRAY_ELEMENT, 0);
+ } else if (c == '.') {
+ output.put11(INNER_TYPE, 0);
+ } else if (c == '*') {
+ output.put11(WILDCARD_BOUND, 0);
+ } else if (c >= '0' && c <= '9') {
+ int typeArg = c - '0';
+ while (typePathIndex < typePathLength) {
+ c = typePath.charAt(typePathIndex++);
+ if (c >= '0' && c <= '9') {
+ typeArg = typeArg * 10 + c - '0';
+ } else if (c == ';') {
+ break;
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+ output.put11(TYPE_ARGUMENT, typeArg);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+ output.data[0] = (byte) (output.length / 2);
+ return new TypePath(output.data, 0);
+ }
+
+ /**
+ * Returns a string representation of this type path. {@link #ARRAY_ELEMENT} steps are represented
+ * with '[', {@link #INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND} steps with '*' and {@link
+ * #TYPE_ARGUMENT} steps with their type argument index in decimal form followed by ';'.
+ */
+ @Override
+ public String toString() {
+ int length = getLength();
+ StringBuilder result = new StringBuilder(length * 2);
+ for (int i = 0; i < length; ++i) {
+ switch (getStep(i)) {
+ case ARRAY_ELEMENT:
+ result.append('[');
+ break;
+ case INNER_TYPE:
+ result.append('.');
+ break;
+ case WILDCARD_BOUND:
+ result.append('*');
+ break;
+ case TYPE_ARGUMENT:
+ result.append(getStepArgument(i)).append(';');
+ break;
+ default:
+ throw new AssertionError();
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Puts the type_path JVMS structure corresponding to the given TypePath into the given
+ * ByteVector.
+ *
+ * @param typePath a TypePath instance, or {@literal null} for empty paths.
+ * @param output where the type path must be put.
+ */
+ static void put(final TypePath typePath, final ByteVector output) {
+ if (typePath == null) {
+ output.putByte(0);
+ } else {
+ int length = typePath.typePathContainer[typePath.typePathOffset] * 2 + 1;
+ output.putByteArray(typePath.typePathContainer, typePath.typePathOffset, length);
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/TypeReference.java b/asm/src/main/java/org/objectweb/asm/TypeReference.java
new file mode 100644
index 00000000..ec927e9d
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/TypeReference.java
@@ -0,0 +1,436 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.objectweb.asm;
+
+/**
+ * A reference to a type appearing in a class, field or method declaration, or on an instruction.
+ * Such a reference designates the part of the class where the referenced type is appearing (e.g. an
+ * 'extends', 'implements' or 'throws' clause, a 'new' instruction, a 'catch' clause, a type cast, a
+ * local variable declaration, etc).
+ *
+ * @author Eric Bruneton
+ */
+public class TypeReference {
+
+ /**
+ * The sort of type references that target a type parameter of a generic class. See {@link
+ * #getSort}.
+ */
+ public static final int CLASS_TYPE_PARAMETER = 0x00;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_TYPE_PARAMETER = 0x01;
+
+ /**
+ * The sort of type references that target the super class of a class or one of the interfaces it
+ * implements. See {@link #getSort}.
+ */
+ public static final int CLASS_EXTENDS = 0x10;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a generic class. See
+ * {@link #getSort}.
+ */
+ public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+
+ /**
+ * The sort of type references that target a bound of a type parameter of a generic method. See
+ * {@link #getSort}.
+ */
+ public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+
+ /** The sort of type references that target the type of a field. See {@link #getSort}. */
+ public static final int FIELD = 0x13;
+
+ /** The sort of type references that target the return type of a method. See {@link #getSort}. */
+ public static final int METHOD_RETURN = 0x14;
+
+ /**
+ * The sort of type references that target the receiver type of a method. See {@link #getSort}.
+ */
+ public static final int METHOD_RECEIVER = 0x15;
+
+ /**
+ * The sort of type references that target the type of a formal parameter of a method. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_FORMAL_PARAMETER = 0x16;
+
+ /**
+ * The sort of type references that target the type of an exception declared in the throws clause
+ * of a method. See {@link #getSort}.
+ */
+ public static final int THROWS = 0x17;
+
+ /**
+ * The sort of type references that target the type of a local variable in a method. See {@link
+ * #getSort}.
+ */
+ public static final int LOCAL_VARIABLE = 0x40;
+
+ /**
+ * The sort of type references that target the type of a resource variable in a method. See {@link
+ * #getSort}.
+ */
+ public static final int RESOURCE_VARIABLE = 0x41;
+
+ /**
+ * The sort of type references that target the type of the exception of a 'catch' clause in a
+ * method. See {@link #getSort}.
+ */
+ public static final int EXCEPTION_PARAMETER = 0x42;
+
+ /**
+ * The sort of type references that target the type declared in an 'instanceof' instruction. See
+ * {@link #getSort}.
+ */
+ public static final int INSTANCEOF = 0x43;
+
+ /**
+ * The sort of type references that target the type of the object created by a 'new' instruction.
+ * See {@link #getSort}.
+ */
+ public static final int NEW = 0x44;
+
+ /**
+ * The sort of type references that target the receiver type of a constructor reference. See
+ * {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_REFERENCE = 0x45;
+
+ /**
+ * The sort of type references that target the receiver type of a method reference. See {@link
+ * #getSort}.
+ */
+ public static final int METHOD_REFERENCE = 0x46;
+
+ /**
+ * The sort of type references that target the type declared in an explicit or implicit cast
+ * instruction. See {@link #getSort}.
+ */
+ public static final int CAST = 0x47;
+
+ /**
+ * The sort of type references that target a type parameter of a generic constructor in a
+ * constructor call. See {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method in a method call.
+ * See {@link #getSort}.
+ */
+ public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+
+ /**
+ * The sort of type references that target a type parameter of a generic constructor in a
+ * constructor reference. See {@link #getSort}.
+ */
+ public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+
+ /**
+ * The sort of type references that target a type parameter of a generic method in a method
+ * reference. See {@link #getSort}.
+ */
+ public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
+ /**
+ * The target_type and target_info structures - as defined in the Java Virtual Machine
+ * Specification (JVMS) - corresponding to this type reference. target_type uses one byte, and all
+ * the target_info union fields use up to 3 bytes (except localvar_target, handled with the
+ * specific method {@link MethodVisitor#visitLocalVariableAnnotation}). Thus, both structures can
+ * be stored in an int.
+ *
+ * <p>This int field stores target_type (called the TypeReference 'sort' in the public API of this
+ * class) in its most significant byte, followed by the target_info fields. Depending on
+ * target_type, 1, 2 or even 3 least significant bytes of this field are unused. target_info
+ * fields which reference bytecode offsets are set to 0 (these offsets are ignored in ClassReader,
+ * and recomputed in MethodWriter).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20">JVMS
+ * 4.7.20</a>
+ * @see <a
+ * href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.20.1">JVMS
+ * 4.7.20.1</a>
+ */
+ private final int targetTypeAndInfo;
+
+ /**
+ * Constructs a new TypeReference.
+ *
+ * @param typeRef the int encoded value of the type reference, as received in a visit method
+ * related to type annotations, such as {@link ClassVisitor#visitTypeAnnotation}.
+ */
+ public TypeReference(final int typeRef) {
+ this.targetTypeAndInfo = typeRef;
+ }
+
+ /**
+ * Returns a type reference of the given sort.
+ *
+ * @param sort one of {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
+ * #LOCAL_VARIABLE}, {@link #RESOURCE_VARIABLE}, {@link #INSTANCEOF}, {@link #NEW}, {@link
+ * #CONSTRUCTOR_REFERENCE}, or {@link #METHOD_REFERENCE}.
+ * @return a type reference of the given sort.
+ */
+ public static TypeReference newTypeReference(final int sort) {
+ return new TypeReference(sort << 24);
+ }
+
+ /**
+ * Returns a reference to a type parameter of a generic class or method.
+ *
+ * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
+ * @param paramIndex the type parameter index.
+ * @return a reference to the given generic class or method type parameter.
+ */
+ public static TypeReference newTypeParameterReference(final int sort, final int paramIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to a type parameter bound of a generic class or method.
+ *
+ * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
+ * @param paramIndex the type parameter index.
+ * @param boundIndex the type bound index within the above type parameters.
+ * @return a reference to the given generic class or method type parameter bound.
+ */
+ public static TypeReference newTypeParameterBoundReference(
+ final int sort, final int paramIndex, final int boundIndex) {
+ return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the super class or to an interface of the 'implements' clause of a
+ * class.
+ *
+ * @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to
+ * reference the super class of the class.
+ * @return a reference to the given super type of a class.
+ */
+ public static TypeReference newSuperTypeReference(final int itfIndex) {
+ return new TypeReference((CLASS_EXTENDS << 24) | ((itfIndex & 0xFFFF) << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a formal parameter of a method.
+ *
+ * @param paramIndex the formal parameter index.
+ * @return a reference to the type of the given method formal parameter.
+ */
+ public static TypeReference newFormalParameterReference(final int paramIndex) {
+ return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
+ }
+
+ /**
+ * Returns a reference to the type of an exception, in a 'throws' clause of a method.
+ *
+ * @param exceptionIndex the index of an exception in a 'throws' clause of a method.
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newExceptionReference(final int exceptionIndex) {
+ return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of the exception declared in a 'catch' clause of a method.
+ *
+ * @param tryCatchBlockIndex the index of a try catch block (using the order in which they are
+ * visited with visitTryCatchBlock).
+ * @return a reference to the type of the given exception.
+ */
+ public static TypeReference newTryCatchReference(final int tryCatchBlockIndex) {
+ return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
+ }
+
+ /**
+ * Returns a reference to the type of a type argument in a constructor or method call or
+ * reference.
+ *
+ * @param sort one of {@link #CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
+ * #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ * @param argIndex the type argument index.
+ * @return a reference to the type of the given type argument.
+ */
+ public static TypeReference newTypeArgumentReference(final int sort, final int argIndex) {
+ return new TypeReference((sort << 24) | argIndex);
+ }
+
+ /**
+ * Returns the sort of this type reference.
+ *
+ * @return one of {@link #CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER}, {@link
+ * #CLASS_EXTENDS}, {@link #CLASS_TYPE_PARAMETER_BOUND}, {@link #METHOD_TYPE_PARAMETER_BOUND},
+ * {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
+ * #METHOD_FORMAL_PARAMETER}, {@link #THROWS}, {@link #LOCAL_VARIABLE}, {@link
+ * #RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER}, {@link #INSTANCEOF}, {@link #NEW},
+ * {@link #CONSTRUCTOR_REFERENCE}, {@link #METHOD_REFERENCE}, {@link #CAST}, {@link
+ * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ */
+ public int getSort() {
+ return targetTypeAndInfo >>> 24;
+ }
+
+ /**
+ * Returns the index of the type parameter referenced by this type reference. This method must
+ * only be used for type references whose sort is {@link #CLASS_TYPE_PARAMETER}, {@link
+ * #METHOD_TYPE_PARAMETER}, {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
+ * #METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeParameterIndex() {
+ return (targetTypeAndInfo & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the type parameter bound, within the type parameter {@link
+ * #getTypeParameterIndex}, referenced by this type reference. This method must only be used for
+ * type references whose sort is {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
+ * #METHOD_TYPE_PARAMETER_BOUND}.
+ *
+ * @return a type parameter bound index.
+ */
+ public int getTypeParameterBoundIndex() {
+ return (targetTypeAndInfo & 0x0000FF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the "super type" of a class that is referenced by this type reference.
+ * This method must only be used for type references whose sort is {@link #CLASS_EXTENDS}.
+ *
+ * @return the index of an interface in the 'implements' clause of a class, or -1 if this type
+ * reference references the type of the super class.
+ */
+ public int getSuperTypeIndex() {
+ return (short) ((targetTypeAndInfo & 0x00FFFF00) >> 8);
+ }
+
+ /**
+ * Returns the index of the formal parameter whose type is referenced by this type reference. This
+ * method must only be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER}.
+ *
+ * @return a formal parameter index.
+ */
+ public int getFormalParameterIndex() {
+ return (targetTypeAndInfo & 0x00FF0000) >> 16;
+ }
+
+ /**
+ * Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced
+ * by this type reference. This method must only be used for type references whose sort is {@link
+ * #THROWS}.
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getExceptionIndex() {
+ return (targetTypeAndInfo & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the try catch block (using the order in which they are visited with
+ * visitTryCatchBlock), whose 'catch' type is referenced by this type reference. This method must
+ * only be used for type references whose sort is {@link #EXCEPTION_PARAMETER} .
+ *
+ * @return the index of an exception in the 'throws' clause of a method.
+ */
+ public int getTryCatchBlockIndex() {
+ return (targetTypeAndInfo & 0x00FFFF00) >> 8;
+ }
+
+ /**
+ * Returns the index of the type argument referenced by this type reference. This method must only
+ * be used for type references whose sort is {@link #CAST}, {@link
+ * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
+ * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
+ *
+ * @return a type parameter index.
+ */
+ public int getTypeArgumentIndex() {
+ return targetTypeAndInfo & 0xFF;
+ }
+
+ /**
+ * Returns the int encoded value of this type reference, suitable for use in visit methods related
+ * to type annotations, like visitTypeAnnotation.
+ *
+ * @return the int encoded value of this type reference.
+ */
+ public int getValue() {
+ return targetTypeAndInfo;
+ }
+
+ /**
+ * Puts the given target_type and target_info JVMS structures into the given ByteVector.
+ *
+ * @param targetTypeAndInfo a target_type and a target_info structures encoded as in {@link
+ * #targetTypeAndInfo}. LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+ * @param output where the type reference must be put.
+ */
+ static void putTarget(final int targetTypeAndInfo, final ByteVector output) {
+ switch (targetTypeAndInfo >>> 24) {
+ case CLASS_TYPE_PARAMETER:
+ case METHOD_TYPE_PARAMETER:
+ case METHOD_FORMAL_PARAMETER:
+ output.putShort(targetTypeAndInfo >>> 16);
+ break;
+ case FIELD:
+ case METHOD_RETURN:
+ case METHOD_RECEIVER:
+ output.putByte(targetTypeAndInfo >>> 24);
+ break;
+ case CAST:
+ case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case METHOD_INVOCATION_TYPE_ARGUMENT:
+ case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case METHOD_REFERENCE_TYPE_ARGUMENT:
+ output.putInt(targetTypeAndInfo);
+ break;
+ case CLASS_EXTENDS:
+ case CLASS_TYPE_PARAMETER_BOUND:
+ case METHOD_TYPE_PARAMETER_BOUND:
+ case THROWS:
+ case EXCEPTION_PARAMETER:
+ case INSTANCEOF:
+ case NEW:
+ case CONSTRUCTOR_REFERENCE:
+ case METHOD_REFERENCE:
+ output.put12(targetTypeAndInfo >>> 24, (targetTypeAndInfo & 0xFFFF00) >> 8);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/package.html b/asm/src/main/java/org/objectweb/asm/package.html
new file mode 100644
index 00000000..db0d8a2e
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/package.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm</title>
+</head>
+<body>
+Provides a small and fast bytecode manipulation framework.
+
+<p>
+The <a href="http://asm.ow2.org/">ASM</a> framework is organized
+around the {@link org.objectweb.asm.ClassVisitor ClassVisitor},
+{@link org.objectweb.asm.FieldVisitor FieldVisitor},
+{@link org.objectweb.asm.MethodVisitor MethodVisitor} and
+{@link org.objectweb.asm.AnnotationVisitor AnnotationVisitor} abstract classes,
+which allow one to visit the fields, methods and annotations of a class,
+including the bytecode instructions of each method.
+
+<p>
+In addition to these main abstract classes, ASM provides a {@link
+org.objectweb.asm.ClassReader ClassReader} class, that can parse an
+existing class and make a given visitor visit it. ASM also provides
+a {@link org.objectweb.asm.ClassWriter ClassWriter} class, which is
+a visitor that generates Java class files.
+
+<p>
+In order to generate a class from scratch, only the {@link
+org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed,
+in order to generate a class, one must just call its visit<em>Xxx</em>
+methods with the appropriate arguments to generate the desired fields
+and methods.
+
+<p>
+In order to modify existing classes, one must use a {@link
+org.objectweb.asm.ClassReader ClassReader} class to analyze
+the original class, a class modifier, and a {@link org.objectweb.asm.ClassWriter
+ClassWriter} to construct the modified class. The class modifier
+is just a {@link org.objectweb.asm.ClassVisitor ClassVisitor}
+that delegates most of the work to another {@link org.objectweb.asm.ClassVisitor
+ClassVisitor}, but that sometimes changes some parameter values,
+or call additional methods, in order to implement the desired
+modification process. In order to make it easier to implement such
+class modifiers, the {@link org.objectweb.asm.ClassVisitor
+ClassVisitor} and {@link org.objectweb.asm.MethodVisitor MethodVisitor}
+classes delegate by default all the method calls they receive to an
+optional visitor.
+
+@since ASM 1.3
+</body>
+</html>
diff --git a/asm/src/main/java/org/objectweb/asm/signature/SignatureReader.java b/asm/src/main/java/org/objectweb/asm/signature/SignatureReader.java
new file mode 100644
index 00000000..304c6f34
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureReader.java
@@ -0,0 +1,252 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+/**
+ * A parser for signature literals, as defined in the Java Virtual Machine Specification (JVMS), to
+ * visit them with a SignatureVisitor.
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1">JVMS
+ * 4.7.9.1</a>
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureReader {
+
+ /** The JVMS signature to be read. */
+ private final String signatureValue;
+
+ /**
+ * Constructs a {@link SignatureReader} for the given signature.
+ *
+ * @param signature A <i>JavaTypeSignature</i>, <i>ClassSignature</i> or <i>MethodSignature</i>.
+ */
+ public SignatureReader(final String signature) {
+ this.signatureValue = signature;
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature is
+ * the one specified in the constructor (see {@link #SignatureReader}). This method is intended to
+ * be called on a {@link SignatureReader} that was created using a <i>ClassSignature</i> (such as
+ * the <code>signature</code> parameter of the {@link org.objectweb.asm.ClassVisitor#visit}
+ * method) or a <i>MethodSignature</i> (such as the <code>signature</code> parameter of the {@link
+ * org.objectweb.asm.ClassVisitor#visitMethod} method).
+ *
+ * @param signatureVistor the visitor that must visit this signature.
+ */
+ public void accept(final SignatureVisitor signatureVistor) {
+ String signature = this.signatureValue;
+ int length = signature.length();
+ int offset; // Current offset in the parsed signature (parsed from left to right).
+ char currentChar; // The signature character at 'offset', or just before.
+
+ // If the signature starts with '<', it starts with TypeParameters, i.e. a formal type parameter
+ // identifier, followed by one or more pair ':',ReferenceTypeSignature (for its class bound and
+ // interface bounds).
+ if (signature.charAt(0) == '<') {
+ // Invariant: offset points to the second character of a formal type parameter name at the
+ // beginning of each iteration of the loop below.
+ offset = 2;
+ do {
+ // The formal type parameter name is everything between offset - 1 and the first ':'.
+ int classBoundStartOffset = signature.indexOf(':', offset);
+ signatureVistor.visitFormalTypeParameter(
+ signature.substring(offset - 1, classBoundStartOffset));
+
+ // If the character after the ':' class bound marker is not the start of a
+ // ReferenceTypeSignature, it means the class bound is empty (which is a valid case).
+ offset = classBoundStartOffset + 1;
+ currentChar = signature.charAt(offset);
+ if (currentChar == 'L' || currentChar == '[' || currentChar == 'T') {
+ offset = parseType(signature, offset, signatureVistor.visitClassBound());
+ }
+
+ // While the character after the class bound or after the last parsed interface bound
+ // is ':', we need to parse another interface bound.
+ while ((currentChar = signature.charAt(offset++)) == ':') {
+ offset = parseType(signature, offset, signatureVistor.visitInterfaceBound());
+ }
+
+ // At this point a TypeParameter has been fully parsed, and we need to parse the next one
+ // (note that currentChar is now the first character of the next TypeParameter, and that
+ // offset points to the second character), unless the character just after this
+ // TypeParameter signals the end of the TypeParameters.
+ } while (currentChar != '>');
+ } else {
+ offset = 0;
+ }
+
+ // If the (optional) TypeParameters is followed by '(' this means we are parsing a
+ // MethodSignature, which has JavaTypeSignature type inside parentheses, followed by a Result
+ // type and optional ThrowsSignature types.
+ if (signature.charAt(offset) == '(') {
+ offset++;
+ while (signature.charAt(offset) != ')') {
+ offset = parseType(signature, offset, signatureVistor.visitParameterType());
+ }
+ // Use offset + 1 to skip ')'.
+ offset = parseType(signature, offset + 1, signatureVistor.visitReturnType());
+ while (offset < length) {
+ // Use offset + 1 to skip the first character of a ThrowsSignature, i.e. '^'.
+ offset = parseType(signature, offset + 1, signatureVistor.visitExceptionType());
+ }
+ } else {
+ // Otherwise we are parsing a ClassSignature (by hypothesis on the method input), which has
+ // one or more ClassTypeSignature for the super class and the implemented interfaces.
+ offset = parseType(signature, offset, signatureVistor.visitSuperclass());
+ while (offset < length) {
+ offset = parseType(signature, offset, signatureVistor.visitInterface());
+ }
+ }
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature is
+ * the one specified in the constructor (see {@link #SignatureReader}). This method is intended to
+ * be called on a {@link SignatureReader} that was created using a <i>JavaTypeSignature</i>, such
+ * as the <code>signature</code> parameter of the {@link
+ * org.objectweb.asm.ClassVisitor#visitField} or {@link
+ * org.objectweb.asm.MethodVisitor#visitLocalVariable} methods.
+ *
+ * @param signatureVisitor the visitor that must visit this signature.
+ */
+ public void acceptType(final SignatureVisitor signatureVisitor) {
+ parseType(signatureValue, 0, signatureVisitor);
+ }
+
+ /**
+ * Parses a JavaTypeSignature and makes the given visitor visit it.
+ *
+ * @param signature a string containing the signature that must be parsed.
+ * @param startOffset index of the first character of the signature to parsed.
+ * @param signatureVisitor the visitor that must visit this signature.
+ * @return the index of the first character after the parsed signature.
+ */
+ private static int parseType(
+ final String signature, final int startOffset, final SignatureVisitor signatureVisitor) {
+ int offset = startOffset; // Current offset in the parsed signature.
+ char currentChar = signature.charAt(offset++); // The signature character at 'offset'.
+
+ // Switch based on the first character of the JavaTypeSignature, which indicates its kind.
+ switch (currentChar) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ case 'V':
+ // Case of a BaseType or a VoidDescriptor.
+ signatureVisitor.visitBaseType(currentChar);
+ return offset;
+
+ case '[':
+ // Case of an ArrayTypeSignature, a '[' followed by a JavaTypeSignature.
+ return parseType(signature, offset, signatureVisitor.visitArrayType());
+
+ case 'T':
+ // Case of TypeVariableSignature, an identifier between 'T' and ';'.
+ int endOffset = signature.indexOf(';', offset);
+ signatureVisitor.visitTypeVariable(signature.substring(offset, endOffset));
+ return endOffset + 1;
+
+ case 'L':
+ // Case of a ClassTypeSignature, which ends with ';'.
+ // These signatures have a main class type followed by zero or more inner class types
+ // (separated by '.'). Each can have type arguments, inside '<' and '>'.
+ int start = offset; // The start offset of the currently parsed main or inner class name.
+ boolean visited = false; // Whether the currently parsed class name has been visited.
+ boolean inner = false; // Whether we are currently parsing an inner class type.
+ // Parses the signature, one character at a time.
+ while (true) {
+ currentChar = signature.charAt(offset++);
+ if (currentChar == '.' || currentChar == ';') {
+ // If a '.' or ';' is encountered, this means we have fully parsed the main class name
+ // or an inner class name. This name may already have been visited it is was followed by
+ // type arguments between '<' and '>'. If not, we need to visit it here.
+ if (!visited) {
+ String name = signature.substring(start, offset - 1);
+ if (inner) {
+ signatureVisitor.visitInnerClassType(name);
+ } else {
+ signatureVisitor.visitClassType(name);
+ }
+ }
+ // If we reached the end of the ClassTypeSignature return, otherwise start the parsing
+ // of a new class name, which is necessarily an inner class name.
+ if (currentChar == ';') {
+ signatureVisitor.visitEnd();
+ break;
+ }
+ start = offset;
+ visited = false;
+ inner = true;
+ } else if (currentChar == '<') {
+ // If a '<' is encountered, this means we have fully parsed the main class name or an
+ // inner class name, and that we now need to parse TypeArguments. First, we need to
+ // visit the parsed class name.
+ String name = signature.substring(start, offset - 1);
+ if (inner) {
+ signatureVisitor.visitInnerClassType(name);
+ } else {
+ signatureVisitor.visitClassType(name);
+ }
+ visited = true;
+ // Now, parse the TypeArgument(s), one at a time.
+ while ((currentChar = signature.charAt(offset)) != '>') {
+ switch (currentChar) {
+ case '*':
+ // Unbounded TypeArgument.
+ ++offset;
+ signatureVisitor.visitTypeArgument();
+ break;
+ case '+':
+ case '-':
+ // Extends or Super TypeArgument. Use offset + 1 to skip the '+' or '-'.
+ offset =
+ parseType(
+ signature, offset + 1, signatureVisitor.visitTypeArgument(currentChar));
+ break;
+ default:
+ // Instanceof TypeArgument. The '=' is implicit.
+ offset = parseType(signature, offset, signatureVisitor.visitTypeArgument('='));
+ break;
+ }
+ }
+ }
+ }
+ return offset;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java b/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java
new file mode 100644
index 00000000..b34df1d6
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java
@@ -0,0 +1,210 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A visitor to visit a generic signature. The methods of this interface must be called in one of
+ * the three following orders (the last one is the only valid order for a {@link SignatureVisitor}
+ * that is returned by a method of this interface):
+ *
+ * <ul>
+ * <li><i>ClassSignature</i> = ( {@code visitFormalTypeParameter} {@code visitClassBound}? {@code
+ * visitInterfaceBound}* )* ({@code visitSuperclass} {@code visitInterface}* )
+ * <li><i>MethodSignature</i> = ( {@code visitFormalTypeParameter} {@code visitClassBound}? {@code
+ * visitInterfaceBound}* )* ({@code visitParameterType}* {@code visitReturnType} {@code
+ * visitExceptionType}* )
+ * <li><i>TypeSignature</i> = {@code visitBaseType} | {@code visitTypeVariable} | {@code
+ * visitArrayType} | ( {@code visitClassType} {@code visitTypeArgument}* ( {@code
+ * visitInnerClassType} {@code visitTypeArgument}* )* {@code visitEnd} ) )
+ * </ul>
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public abstract class SignatureVisitor {
+
+ /** Wildcard for an "extends" type argument. */
+ public static final char EXTENDS = '+';
+
+ /** Wildcard for a "super" type argument. */
+ public static final char SUPER = '-';
+
+ /** Wildcard for a normal type argument. */
+ public static final char INSTANCEOF = '=';
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected final int api;
+
+ /**
+ * Constructs a new {@link SignatureVisitor}.
+ *
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
+ */
+ protected SignatureVisitor(final int api) {
+ if (api != Opcodes.ASM9
+ && api != Opcodes.ASM8
+ && api != Opcodes.ASM7
+ && api != Opcodes.ASM6
+ && api != Opcodes.ASM5
+ && api != Opcodes.ASM4
+ && api != Opcodes.ASM10_EXPERIMENTAL) {
+ throw new IllegalArgumentException("Unsupported api " + api);
+ }
+ this.api = api;
+ }
+
+ /**
+ * Visits a formal type parameter.
+ *
+ * @param name the name of the formal parameter.
+ */
+ public void visitFormalTypeParameter(final String name) {}
+
+ /**
+ * Visits the class bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the class bound.
+ */
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ /**
+ * Visits an interface bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the interface bound.
+ */
+ public SignatureVisitor visitInterfaceBound() {
+ return this;
+ }
+
+ /**
+ * Visits the type of the super class.
+ *
+ * @return a non null visitor to visit the signature of the super class type.
+ */
+ public SignatureVisitor visitSuperclass() {
+ return this;
+ }
+
+ /**
+ * Visits the type of an interface implemented by the class.
+ *
+ * @return a non null visitor to visit the signature of the interface type.
+ */
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ /**
+ * Visits the type of a method parameter.
+ *
+ * @return a non null visitor to visit the signature of the parameter type.
+ */
+ public SignatureVisitor visitParameterType() {
+ return this;
+ }
+
+ /**
+ * Visits the return type of the method.
+ *
+ * @return a non null visitor to visit the signature of the return type.
+ */
+ public SignatureVisitor visitReturnType() {
+ return this;
+ }
+
+ /**
+ * Visits the type of a method exception.
+ *
+ * @return a non null visitor to visit the signature of the exception type.
+ */
+ public SignatureVisitor visitExceptionType() {
+ return this;
+ }
+
+ /**
+ * Visits a signature corresponding to a primitive type.
+ *
+ * @param descriptor the descriptor of the primitive type, or 'V' for {@code void} .
+ */
+ public void visitBaseType(final char descriptor) {}
+
+ /**
+ * Visits a signature corresponding to a type variable.
+ *
+ * @param name the name of the type variable.
+ */
+ public void visitTypeVariable(final String name) {}
+
+ /**
+ * Visits a signature corresponding to an array type.
+ *
+ * @return a non null visitor to visit the signature of the array element type.
+ */
+ public SignatureVisitor visitArrayType() {
+ return this;
+ }
+
+ /**
+ * Starts the visit of a signature corresponding to a class or interface type.
+ *
+ * @param name the internal name of the class or interface (see {@link
+ * org.objectweb.asm.Type#getInternalName()}).
+ */
+ public void visitClassType(final String name) {}
+
+ /**
+ * Visits an inner class.
+ *
+ * @param name the local name of the inner class in its enclosing class.
+ */
+ public void visitInnerClassType(final String name) {}
+
+ /** Visits an unbounded type argument of the last visited class or inner class type. */
+ public void visitTypeArgument() {}
+
+ /**
+ * Visits a type argument of the last visited class or inner class type.
+ *
+ * @param wildcard '+', '-' or '='.
+ * @return a non null visitor to visit the signature of the type argument.
+ */
+ public SignatureVisitor visitTypeArgument(final char wildcard) {
+ return this;
+ }
+
+ /** Ends the visit of a signature corresponding to a class or interface type. */
+ public void visitEnd() {}
+}
diff --git a/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java b/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
new file mode 100644
index 00000000..c8d80f92
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureWriter.java
@@ -0,0 +1,247 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A SignatureVisitor that generates signature literals, as defined in the Java Virtual Machine
+ * Specification (JVMS).
+ *
+ * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1">JVMS
+ * 4.7.9.1</a>
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureWriter extends SignatureVisitor {
+
+ /** The builder used to construct the visited signature. */
+ private final StringBuilder stringBuilder;
+
+ /** Whether the visited signature contains formal type parameters. */
+ private boolean hasFormals;
+
+ /** Whether the visited signature contains method parameter types. */
+ private boolean hasParameters;
+
+ /**
+ * The stack used to keep track of class types that have arguments. Each element of this stack is
+ * a boolean encoded in one bit. The top of the stack is the least significant bit. The bottom of
+ * the stack is a sentinel element always equal to 1 (used to detect when the stack is full).
+ * Pushing false = {@code <<= 1}, pushing true = {@code ( <<= 1) | 1}, popping = {@code >>>= 1}.
+ *
+ * <p>Class type arguments must be surrounded with '&lt;' and '&gt;' and, because
+ *
+ * <ol>
+ * <li>class types can be nested (because type arguments can themselves be class types),
+ * <li>SignatureWriter always returns 'this' in each visit* method (to avoid allocating new
+ * SignatureWriter instances),
+ * </ol>
+ *
+ * <p>we need a stack to properly balance these angle brackets. A new element is pushed on this
+ * stack for each new visited type, and popped when the visit of this type ends (either in
+ * visitEnd, or because visitInnerClassType is called).
+ */
+ private int argumentStack = 1;
+
+ /** Constructs a new {@link SignatureWriter}. */
+ public SignatureWriter() {
+ this(new StringBuilder());
+ }
+
+ private SignatureWriter(final StringBuilder stringBuilder) {
+ super(/* latest api =*/ Opcodes.ASM9);
+ this.stringBuilder = stringBuilder;
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Implementation of the SignatureVisitor interface
+ // -----------------------------------------------------------------------------------------------
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ if (!hasFormals) {
+ hasFormals = true;
+ stringBuilder.append('<');
+ }
+ stringBuilder.append(name);
+ stringBuilder.append(':');
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ stringBuilder.append(':');
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ endFormals();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ endFormals();
+ if (!hasParameters) {
+ hasParameters = true;
+ stringBuilder.append('(');
+ }
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ endFormals();
+ if (!hasParameters) {
+ stringBuilder.append('(');
+ }
+ stringBuilder.append(')');
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ stringBuilder.append('^');
+ return this;
+ }
+
+ @Override
+ public void visitBaseType(final char descriptor) {
+ stringBuilder.append(descriptor);
+ }
+
+ @Override
+ public void visitTypeVariable(final String name) {
+ stringBuilder.append('T');
+ stringBuilder.append(name);
+ stringBuilder.append(';');
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ stringBuilder.append('[');
+ return this;
+ }
+
+ @Override
+ public void visitClassType(final String name) {
+ stringBuilder.append('L');
+ stringBuilder.append(name);
+ // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as
+ // we can tell at this point).
+ argumentStack <<= 1;
+ }
+
+ @Override
+ public void visitInnerClassType(final String name) {
+ endArguments();
+ stringBuilder.append('.');
+ stringBuilder.append(name);
+ // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as
+ // we can tell at this point).
+ argumentStack <<= 1;
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ // If the top of the stack is 'false', this means we are visiting the first type argument of the
+ // currently visited type. We therefore need to append a '<', and to replace the top stack
+ // element with 'true' (meaning that the current type does have type arguments).
+ if ((argumentStack & 1) == 0) {
+ argumentStack |= 1;
+ stringBuilder.append('<');
+ }
+ stringBuilder.append('*');
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(final char wildcard) {
+ // If the top of the stack is 'false', this means we are visiting the first type argument of the
+ // currently visited type. We therefore need to append a '<', and to replace the top stack
+ // element with 'true' (meaning that the current type does have type arguments).
+ if ((argumentStack & 1) == 0) {
+ argumentStack |= 1;
+ stringBuilder.append('<');
+ }
+ if (wildcard != '=') {
+ stringBuilder.append(wildcard);
+ }
+ // If the stack is full, start a nested one by returning a new SignatureWriter.
+ return (argumentStack & (1 << 31)) == 0 ? this : new SignatureWriter(stringBuilder);
+ }
+
+ @Override
+ public void visitEnd() {
+ endArguments();
+ stringBuilder.append(';');
+ }
+
+ /**
+ * Returns the signature that was built by this signature writer.
+ *
+ * @return the signature that was built by this signature writer.
+ */
+ @Override
+ public String toString() {
+ return stringBuilder.toString();
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Utility methods
+ // -----------------------------------------------------------------------------------------------
+
+ /** Ends the formal type parameters section of the signature. */
+ private void endFormals() {
+ if (hasFormals) {
+ hasFormals = false;
+ stringBuilder.append('>');
+ }
+ }
+
+ /** Ends the type arguments of a class or inner class type. */
+ private void endArguments() {
+ // If the top of the stack is 'true', this means that some type arguments have been visited for
+ // the type whose visit is now ending. We therefore need to append a '>', and to pop one element
+ // from the stack.
+ if ((argumentStack & 1) == 1) {
+ stringBuilder.append('>');
+ }
+ argumentStack >>>= 1;
+ }
+}
diff --git a/asm/src/main/java/org/objectweb/asm/signature/package.html b/asm/src/main/java/org/objectweb/asm/signature/package.html
new file mode 100644
index 00000000..d1657d41
--- /dev/null
+++ b/asm/src/main/java/org/objectweb/asm/signature/package.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en">
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<head>
+ <title>Package org.objectweb.asm.signature</title>
+</head>
+<body>
+Provides support for type signatures.
+
+@since ASM 2.0
+</body>
+</html>
diff --git a/asm/src/test/java/org/objectweb/asm/AnnotationVisitorTest.java b/asm/src/test/java/org/objectweb/asm/AnnotationVisitorTest.java
new file mode 100644
index 00000000..6b06d081
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/AnnotationVisitorTest.java
@@ -0,0 +1,300 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link AnnotationVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class AnnotationVisitorTest extends AsmTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new AnnotationVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new AnnotationVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ AnnotationVisitor delegate = new AnnotationVisitor(Opcodes.ASM4) {};
+ AnnotationVisitor visitor = new AnnotationVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+
+ /**
+ * Tests that ClassReader accepts visitor which return null AnnotationVisitor, and that returning
+ * null AnnotationVisitor is equivalent to returning an EmptyAnnotationVisitor.
+ */
+ @ParameterizedTest
+ @MethodSource("allClassesAndAllApis")
+ void testReadAndWrite_removeOrDeleteAnnotations(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassWriter removedAnnotationsClassWriter = new ClassWriter(0);
+ ClassWriter deletedAnnotationsClassWriter = new ClassWriter(0);
+ ClassVisitor removeAnnotationsAdapter =
+ new RemoveAnnotationsAdapter(apiParameter.value(), removedAnnotationsClassWriter);
+ ClassVisitor deleteAnnotationsAdapter =
+ new DeleteAnnotationsAdapter(apiParameter.value(), deletedAnnotationsClassWriter);
+
+ Executable removeAnnotations = () -> classReader.accept(removeAnnotationsAdapter, 0);
+ Executable deleteAnnotations = () -> classReader.accept(deleteAnnotationsAdapter, 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception removeException =
+ assertThrows(UnsupportedOperationException.class, removeAnnotations);
+ Exception deleteException =
+ assertThrows(UnsupportedOperationException.class, deleteAnnotations);
+ assertTrue(removeException.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ assertTrue(deleteException.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(removeAnnotations);
+ assertDoesNotThrow(deleteAnnotations);
+ assertEquals(
+ new ClassFile(removedAnnotationsClassWriter.toByteArray()),
+ new ClassFile(deletedAnnotationsClassWriter.toByteArray()));
+ }
+ }
+
+ private static class EmptyAnnotationVisitor extends AnnotationVisitor {
+
+ EmptyAnnotationVisitor(final int api) {
+ super(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ return this;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ return this;
+ }
+ }
+
+ private static class RemoveAnnotationsAdapter extends ClassVisitor {
+
+ RemoveAnnotationsAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ return new EmptyAnnotationVisitor(api);
+ }
+ };
+ }
+ }
+
+ private static class DeleteAnnotationsAdapter extends ClassVisitor {
+
+ DeleteAnnotationsAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ return null;
+ }
+ };
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/AttributeTest.java b/asm/src/test/java/org/objectweb/asm/AttributeTest.java
new file mode 100644
index 00000000..d137d621
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/AttributeTest.java
@@ -0,0 +1,51 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link Attribute}.
+ *
+ * @author Eric Bruneton
+ */
+class AttributeTest {
+
+ @Test
+ void testIsUnknown() {
+ assertTrue(new Attribute("Comment").isUnknown());
+ }
+
+ @Test
+ void testGetLabels() {
+ assertArrayEquals(new Label[0], new Attribute("Comment").getLabels());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ByteVectorTest.java b/asm/src/test/java/org/objectweb/asm/ByteVectorTest.java
new file mode 100644
index 00000000..6c47900b
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ByteVectorTest.java
@@ -0,0 +1,192 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+/**
+ * Unit tests for {@link ByteVector}.
+ *
+ * @author Eric Bruneton
+ */
+class ByteVectorTest {
+
+ @Test
+ void testPutByte() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putByte(1);
+
+ assertArrayEquals(new byte[] {1}, toArray(byteVector));
+ assertEquals(1, byteVector.size());
+ }
+
+ @Test
+ void testPut11() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.put11(1, 2);
+
+ assertArrayEquals(new byte[] {1, 2}, toArray(byteVector));
+ assertEquals(2, byteVector.size());
+ }
+
+ @Test
+ void testPutShort() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putShort(0x0102);
+
+ assertArrayEquals(new byte[] {1, 2}, toArray(byteVector));
+ assertEquals(2, byteVector.size());
+ }
+
+ @Test
+ void testPut12() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.put12(1, 0x0203);
+
+ assertArrayEquals(new byte[] {1, 2, 3}, toArray(byteVector));
+ assertEquals(3, byteVector.size());
+ }
+
+ @Test
+ void testPut112() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.put112(1, 2, 0x0304);
+
+ assertArrayEquals(new byte[] {1, 2, 3, 4}, toArray(byteVector));
+ assertEquals(4, byteVector.size());
+ }
+
+ @Test
+ void testPutInt() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putInt(0x01020304);
+
+ assertArrayEquals(new byte[] {1, 2, 3, 4}, toArray(byteVector));
+ assertEquals(4, byteVector.size());
+ }
+
+ @Test
+ void testPut122() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.put122(1, 0x0203, 0x0405);
+
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5}, toArray(byteVector));
+ assertEquals(5, byteVector.size());
+ }
+
+ @Test
+ void testPutLong() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putLong(0x0102030405060708L);
+
+ assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, toArray(byteVector));
+ assertEquals(8, byteVector.size());
+ }
+
+ @Test
+ void testPutUtf8_ascii() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putUTF8("abc");
+
+ assertArrayEquals(new byte[] {0, 3, 'a', 'b', 'c'}, toArray(byteVector));
+ assertEquals(5, byteVector.size());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = {65535, 65536})
+ void testPutUtf8_ascii_tooLarge(final int size) {
+ ByteVector byteVector = new ByteVector(0);
+ char[] charBuffer = new char[size];
+ Arrays.fill(charBuffer, 'A');
+
+ Executable putUtf8 = () -> byteVector.putUTF8(new String(charBuffer));
+
+ if (size > 65535) {
+ Exception exception = assertThrows(IllegalArgumentException.class, putUtf8);
+ assertEquals("UTF8 string too large", exception.getMessage());
+ } else {
+ assertDoesNotThrow(putUtf8);
+ }
+ }
+
+ @Test
+ void testPutUtf8_unicode() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putUTF8(new String(new char[] {'a', 0x0000, 0x0080, 0x0800}));
+
+ assertArrayEquals(
+ new byte[] {0, 8, 'a', -64, -128, -62, -128, -32, -96, -128}, toArray(byteVector));
+ }
+
+ @Test
+ void testPutUtf8_unicode_tooLarge() {
+ ByteVector byteVector = new ByteVector(0);
+ char[] charBuffer = new char[32768];
+ Arrays.fill(charBuffer, (char) 0x07FF);
+
+ Executable putUtf8 = () -> byteVector.putUTF8(new String(charBuffer));
+
+ Exception exception = assertThrows(IllegalArgumentException.class, putUtf8);
+ assertEquals("UTF8 string too large", exception.getMessage());
+ }
+
+ @Test
+ void testPutByteArray() {
+ ByteVector byteVector = new ByteVector(0);
+
+ byteVector.putByteArray(new byte[] {0, 1, 2, 3, 4, 5}, 1, 3);
+
+ assertArrayEquals(new byte[] {1, 2, 3}, toArray(byteVector));
+ assertEquals(3, byteVector.size());
+ }
+
+ private static byte[] toArray(final ByteVector byteVector) {
+ byte[] result = new byte[byteVector.length];
+ System.arraycopy(byteVector.data, 0, result, 0, byteVector.length);
+ return result;
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java
new file mode 100644
index 00000000..95a968f8
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java
@@ -0,0 +1,761 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Duration;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link ClassReader}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassReaderTest extends AsmTest implements Opcodes {
+
+ @Test
+ void testReadByte() throws IOException {
+ ClassReader classReader = new ClassReader(getClass().getName());
+
+ assertEquals(classReader.classFileBuffer[0] & 0xFF, classReader.readByte(0));
+ }
+
+ @Test
+ void testGetItem() throws IOException {
+ ClassReader classReader = new ClassReader(getClass().getName());
+
+ int item = classReader.getItem(1);
+
+ assertTrue(item >= 10);
+ assertTrue(item < classReader.header);
+ }
+
+ @Test
+ void testGetAccess() throws Exception {
+ String name = getClass().getName();
+
+ assertEquals(ACC_SUPER, new ClassReader(name).getAccess());
+ }
+
+ @Test
+ void testGetClassName() throws Exception {
+ String name = getClass().getName();
+
+ assertEquals(name.replace('.', '/'), new ClassReader(name).getClassName());
+ }
+
+ @Test
+ void testGetSuperName() throws Exception {
+ ClassReader thisClassReader = new ClassReader(getClass().getName());
+ ClassReader objectClassReader = new ClassReader(Object.class.getName());
+
+ assertEquals(AsmTest.class.getName().replace('.', '/'), thisClassReader.getSuperName());
+ assertEquals(null, objectClassReader.getSuperName());
+ }
+
+ @Test
+ void testGetInterfaces() throws Exception {
+ ClassReader classReader = new ClassReader(getClass().getName());
+
+ String[] interfaces = classReader.getInterfaces();
+
+ assertNotNull(interfaces);
+ assertEquals(1, interfaces.length);
+ assertEquals(Opcodes.class.getName().replace('.', '/'), interfaces[0]);
+ }
+
+ @Test
+ void testGetInterfaces_empty() throws Exception {
+ ClassReader classReader = new ClassReader(Opcodes.class.getName());
+
+ String[] interfaces = classReader.getInterfaces();
+
+ assertNotNull(interfaces);
+ }
+
+ /** Tests {@link ClassReader#ClassReader(byte[])}. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testByteArrayConstructor(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+
+ assertNotEquals(0, classReader.getAccess());
+ assertEquals(classParameter.getInternalName(), classReader.getClassName());
+ if (classParameter.getInternalName().equals("module-info")) {
+ assertNull(classReader.getSuperName());
+ } else {
+ assertTrue(classReader.getSuperName().startsWith("java"));
+ }
+ assertNotNull(classReader.getInterfaces());
+ }
+
+ /** Tests {@link ClassReader#ClassReader(byte[],int,int)} and the basic ClassReader accessors. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_LATEST_API)
+ void testByteArrayConstructor_withOffset(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ byte[] byteBuffer = new byte[classFile.length + 1];
+ System.arraycopy(classFile, 0, byteBuffer, 1, classFile.length);
+
+ ClassReader classReader = new ClassReader(byteBuffer, 1, classFile.length);
+
+ assertNotEquals(0, classReader.getAccess());
+ assertEquals(classParameter.getInternalName(), classReader.getClassName());
+ if (classParameter.getInternalName().equals("module-info")) {
+ assertNull(classReader.getSuperName());
+ } else {
+ assertTrue(classReader.getSuperName().startsWith("java"));
+ }
+ assertNotNull(classReader.getInterfaces());
+ AtomicInteger classVersion = new AtomicInteger(0);
+ classReader.accept(
+ new ClassVisitor(apiParameter.value()) {
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ classVersion.set(version);
+ }
+ },
+ 0);
+ assertTrue((classVersion.get() & 0xFFFF) >= (Opcodes.V1_1 & 0xFFFF));
+ }
+
+ /**
+ * Tests that constructing a ClassReader fails if the class version or constant pool is invalid or
+ * not supported.
+ */
+ @ParameterizedTest
+ @EnumSource(InvalidClass.class)
+ void testByteArrayConstructor_invalidClassHeader(final InvalidClass invalidClass) {
+ assumeTrue(
+ invalidClass == InvalidClass.INVALID_CLASS_VERSION
+ || invalidClass == InvalidClass.INVALID_CP_INFO_TAG);
+
+ Executable constructor = () -> new ClassReader(invalidClass.getBytes());
+
+ assertThrows(IllegalArgumentException.class, constructor);
+ }
+
+ /** Tests {@link ClassReader#ClassReader(String)} and the basic ClassReader accessors. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testStringConstructor(final PrecompiledClass classParameter, final Api apiParameter)
+ throws IOException {
+ ClassReader classReader = new ClassReader(classParameter.getName());
+
+ assertNotEquals(0, classReader.getAccess());
+ assertEquals(classParameter.getInternalName(), classReader.getClassName());
+ if (classParameter.getInternalName().equals("module-info")) {
+ assertNull(classReader.getSuperName());
+ } else {
+ assertTrue(classReader.getSuperName().startsWith("java"));
+ }
+ assertNotNull(classReader.getInterfaces());
+ }
+
+ /**
+ * Tests {@link ClassReader#ClassReader(java.io.InputStream)} and the basic ClassReader accessors.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testStreamConstructor(final PrecompiledClass classParameter, final Api apiParameter)
+ throws IOException {
+ ClassReader classReader;
+ try (InputStream inputStream =
+ ClassLoader.getSystemResourceAsStream(
+ classParameter.getName().replace('.', '/') + ".class")) {
+ classReader = new ClassReader(inputStream);
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+
+ assertNotEquals(0, classReader.getAccess());
+ assertEquals(classParameter.getInternalName(), classReader.getClassName());
+ if (classParameter.getInternalName().equals("module-info")) {
+ assertNull(classReader.getSuperName());
+ } else {
+ assertTrue(classReader.getSuperName().startsWith("java"));
+ }
+ assertNotNull(classReader.getInterfaces());
+ }
+
+ @Test
+ void testStreamConstructor_nullStream() {
+ Executable constructor = () -> new ClassReader((InputStream) null);
+
+ Exception exception = assertThrows(IOException.class, constructor);
+ assertEquals("Class not found", exception.getMessage());
+ }
+
+ /** Tests {@link ClassReader#ClassReader(java.io.InputStream)} with an empty stream. */
+ @Test
+ void testStreamConstructor_emptyStream() throws IOException {
+ try (InputStream inputStream =
+ new InputStream() {
+
+ @Override
+ public int available() throws IOException {
+ return 0;
+ }
+
+ @Override
+ public int read() throws IOException {
+ return -1;
+ }
+ }) {
+ Executable streamConstructor = () -> new ClassReader(inputStream);
+
+ assertTimeoutPreemptively(
+ Duration.ofMillis(100),
+ () -> assertThrows(ArrayIndexOutOfBoundsException.class, streamConstructor));
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+
+ /** Tests the ClassReader accept method with an empty visitor. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new EmptyClassVisitor(apiParameter.value());
+
+ Executable accept = () -> classReader.accept(classVisitor, 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /** Tests the ClassReader accept method with an empty visitor and SKIP_DEBUG. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor_skipDebug(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new EmptyClassVisitor(apiParameter.value());
+
+ Executable accept = () -> classReader.accept(classVisitor, ClassReader.SKIP_DEBUG);
+
+ // The following jdk8 classes contain MethodParameters attributes which require ASM5. Here we
+ // skip these attributes with SKIP_DEBUG, and these classes contain no other features requiring
+ // ASM5 or more, so they can be read with ASM4.
+ if (classParameter.isMoreRecentThan(apiParameter)
+ && classParameter != PrecompiledClass.JDK8_ALL_FRAMES
+ && classParameter != PrecompiledClass.JDK8_ALL_STRUCTURES
+ && classParameter != PrecompiledClass.JDK8_ANONYMOUS_INNER_CLASS
+ && classParameter != PrecompiledClass.JDK8_INNER_CLASS
+ && classParameter != PrecompiledClass.JDK8_LARGE_METHOD) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /** Tests the ClassReader accept method with an empty visitor and EXPAND_FRAMES. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor_expandFrames(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new EmptyClassVisitor(apiParameter.value());
+
+ Executable accept = () -> classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /** Tests the ClassReader accept method with an empty visitor and SKIP_FRAMES. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor_skipFrames(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new EmptyClassVisitor(apiParameter.value());
+
+ Executable accept = () -> classReader.accept(classVisitor, ClassReader.SKIP_FRAMES);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /** Tests the ClassReader accept method with an empty visitor and SKIP_CODE. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor_skipCode(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new EmptyClassVisitor(apiParameter.value());
+
+ Executable accept = () -> classReader.accept(classVisitor, ClassReader.SKIP_CODE);
+
+ // jdk8.ArtificialStructures contains structures which require ASM5, but only inside the method
+ // code. Here we skip the code, so this class can be read with ASM4. Likewise for
+ // jdk11.AllInstructions.
+ if (classParameter.isMoreRecentThan(apiParameter)
+ && classParameter != PrecompiledClass.JDK8_ARTIFICIAL_STRUCTURES
+ && classParameter != PrecompiledClass.JDK11_ALL_INSTRUCTIONS) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /**
+ * Tests the ClassReader accept method with a visitor that skips fields, methods, members,
+ * modules, nest host, permitted subclasses and record.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_emptyVisitor_skipFieldMethodAndModuleContent(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor =
+ new EmptyClassVisitor(apiParameter.value()) {
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ // access may contain ACC_RECORD
+ }
+
+ @Override
+ public ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ return null;
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ return null;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return null;
+ }
+
+ @Override
+ public void visitNestHost(final String nestHost) {}
+
+ @Override
+ public void visitNestMember(final String nestMember) {}
+
+ @Override
+ public void visitPermittedSubclass(final String permittedSubclass) {}
+ };
+
+ Executable accept = () -> classReader.accept(classVisitor, 0);
+
+ assertDoesNotThrow(accept);
+ }
+
+ /** Tests the ClassReader accept method with a class whose content is invalid. */
+ @ParameterizedTest
+ @EnumSource(InvalidClass.class)
+ void testAccept_emptyVisitor_invalidClass(final InvalidClass invalidClass) {
+ assumeFalse(
+ invalidClass == InvalidClass.INVALID_CLASS_VERSION
+ || invalidClass == InvalidClass.INVALID_CP_INFO_TAG);
+ ClassReader classReader = new ClassReader(invalidClass.getBytes());
+
+ Executable accept =
+ () -> classReader.accept(new EmptyClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL), 0);
+
+ if (invalidClass == InvalidClass.INVALID_CONSTANT_POOL_INDEX
+ || invalidClass == InvalidClass.INVALID_CONSTANT_POOL_REFERENCE
+ || invalidClass == InvalidClass.INVALID_BYTECODE_OFFSET) {
+ Exception exception = assertThrows(ArrayIndexOutOfBoundsException.class, accept);
+ Matcher matcher = Pattern.compile("\\d+").matcher(exception.getMessage());
+ assertTrue(matcher.find() && Integer.valueOf(matcher.group()) > 0);
+ } else {
+ assertThrows(IllegalArgumentException.class, accept);
+ }
+ }
+
+ /** Tests the ClassReader accept method with a default visitor. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_defaultVisitor(final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor = new ClassVisitor(apiParameter.value()) {};
+
+ Executable accept = () -> classReader.accept(classVisitor, 0);
+
+ boolean hasPermittedSubclasses = classParameter == PrecompiledClass.JDK15_ALL_STRUCTURES;
+ boolean hasRecord =
+ classParameter == PrecompiledClass.JDK14_ALL_STRUCTURES_RECORD
+ || classParameter == PrecompiledClass.JDK14_ALL_STRUCTURES_EMPTY_RECORD;
+ boolean hasNestHostOrMembers =
+ classParameter == PrecompiledClass.JDK11_ALL_STRUCTURES
+ || classParameter == PrecompiledClass.JDK11_ALL_STRUCTURES_NESTED;
+ boolean hasModules = classParameter == PrecompiledClass.JDK9_MODULE;
+ boolean hasTypeAnnotations = classParameter == PrecompiledClass.JDK8_ALL_STRUCTURES;
+ if ((hasPermittedSubclasses && apiParameter.value() < ASM9)
+ || (hasRecord && apiParameter.value() < ASM8)
+ || (hasNestHostOrMembers && apiParameter.value() < ASM7)
+ || (hasModules && apiParameter.value() < ASM6)
+ || (hasTypeAnnotations && apiParameter.value() < ASM5)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ /**
+ * Tests the ClassReader accept method with default annotation, field, method and module visitors.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testAccept_defaultAnnotationFieldMethodAndModuleVisitors(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ ClassVisitor classVisitor =
+ new EmptyClassVisitor(apiParameter.value()) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new AnnotationVisitor(api) {};
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationVisitor(api) {};
+ }
+
+ @Override
+ public ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ super.visitModule(name, access, version);
+ return new ModuleVisitor(api) {};
+ }
+
+ @Override
+ public RecordComponentVisitor visitRecordComponent(
+ final String name, final String descriptor, final String signature) {
+ super.visitRecordComponent(name, descriptor, signature);
+ return new RecordComponentVisitor(api) {
+ @Override
+ public AnnotationVisitor visitAnnotation(
+ final String descriptor, final boolean visible) {
+ return new AnnotationVisitor(api) {};
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationVisitor(api) {};
+ }
+ };
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return new FieldVisitor(api) {};
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(api) {};
+ }
+ };
+
+ Executable accept = () -> classReader.accept(classVisitor, 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, accept);
+ if (!exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN)) {
+ throw new AssertionError("invalid error message");
+ }
+ } else {
+ assertDoesNotThrow(accept);
+ }
+ }
+
+ @Test
+ void testAccept_parameterAnnotationIndices() {
+ ClassReader classReader = new ClassReader(PrecompiledClass.JDK5_LOCAL_CLASS.getBytes());
+ AtomicInteger parameterIndex = new AtomicInteger(-1);
+ ClassVisitor readParameterIndexVisitor =
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(api, null) {
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ if (descriptor.equals("Ljava/lang/Deprecated;")) {
+ parameterIndex.set(parameter);
+ }
+ return null;
+ }
+ };
+ }
+ };
+
+ classReader.accept(readParameterIndexVisitor, 0);
+
+ assertEquals(0, parameterIndex.get());
+ }
+
+ @Test
+ void testAccept_previewClass() {
+ byte[] classFile = PrecompiledClass.JDK11_ALL_INSTRUCTIONS.getBytes();
+ // Set the minor version to 65535.
+ classFile[4] = (byte) 0xFF;
+ classFile[5] = (byte) 0xFF;
+ ClassReader classReader = new ClassReader(classFile);
+ AtomicInteger classVersion = new AtomicInteger(0);
+ ClassVisitor readVersionVisitor =
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ classVersion.set(version);
+ }
+ };
+
+ classReader.accept(readVersionVisitor, 0);
+
+ assertEquals(Opcodes.V_PREVIEW, classVersion.get() & Opcodes.V_PREVIEW);
+ }
+
+ private static class EmptyClassVisitor extends ClassVisitor {
+
+ final AnnotationVisitor annotationVisitor =
+ new AnnotationVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ return this;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ return this;
+ }
+ };
+
+ EmptyClassVisitor(final int api) {
+ super(api);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return new FieldVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+ };
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ return annotationVisitor;
+ }
+ };
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java
new file mode 100644
index 00000000..5c04868f
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java
@@ -0,0 +1,692 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link ClassVisitor}. Also tests {@link FieldVisitor}, {@ink MethodVisitor},
+ * {@link ModuleVisitor} and {@link AnnotationVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassVisitorTest extends AsmTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new ClassVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new ClassVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ ClassVisitor delegate = new ClassVisitor(Opcodes.ASM4) {};
+ ClassVisitor visitor = new ClassVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+
+ /**
+ * Tests that classes are unchanged when transformed with a ClassReader -> class adapter ->
+ * ClassWriter chain, where "class adapter" is a ClassVisitor which returns FieldVisitor,
+ * MethodVisitor, ModuleVisitor and AnnotationVisitor instances.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_emptyVisitor(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassAdapter classAdapter = new ClassAdapter(apiParameter.value(), classWriter);
+
+ Executable transform = () -> classReader.accept(classAdapter, attributes(), 0);
+
+ if (classParameter.isMoreRecentThan(apiParameter)) {
+ Exception exception = assertThrows(UnsupportedOperationException.class, transform);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ } else {
+ assertDoesNotThrow(transform);
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+ }
+
+ /**
+ * Tests that a ClassReader -> class adapter -> ClassWriter chain gives the same result with or
+ * without the copy pool option, and a class adapter that changes the method exceptions.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_copyPool_changeMethodExceptions(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassWriter classWriterWithCopyPool = new ClassWriter(classReader, 0);
+
+ classReader.accept(new ChangeExceptionAdapter(classWriter), attributes(), 0);
+ classReader.accept(new ChangeExceptionAdapter(classWriterWithCopyPool), attributes(), 0);
+
+ assertEquals(
+ new ClassFile(classWriter.toByteArray()),
+ new ClassFile(classWriterWithCopyPool.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> class adapter -> ClassWriter chain gives the same result with or
+ * without the copy pool option, and a class adapter that changes the deprecated method flags.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_copyPool_changeMethodDeprecatedFlag(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassWriter classWriterWithCopyPool = new ClassWriter(classReader, 0);
+ int access = Opcodes.ACC_DEPRECATED;
+
+ classReader.accept(new ChangeAccessAdapter(classWriter, access), attributes(), 0);
+ classReader.accept(new ChangeAccessAdapter(classWriterWithCopyPool, access), attributes(), 0);
+
+ assertEquals(
+ new ClassFile(classWriter.toByteArray()),
+ new ClassFile(classWriterWithCopyPool.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> class adapter -> ClassWriter chain gives the same result with or
+ * without the copy pool option, and a class adapter that changes the synthetic method flags.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_copyPool_changeMethodSyntheticFlag(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassWriter classWriterWithCopyPool = new ClassWriter(classReader, 0);
+ int access = Opcodes.ACC_SYNTHETIC;
+
+ classReader.accept(new ChangeAccessAdapter(classWriter, access), attributes(), 0);
+ classReader.accept(new ChangeAccessAdapter(classWriterWithCopyPool, access), attributes(), 0);
+
+ assertEquals(
+ new ClassFile(classWriter.toByteArray()),
+ new ClassFile(classWriterWithCopyPool.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> class adapter -> ClassWriter chain gives the same result with or
+ * without the copy pool option, and a class adapter that changes the class version (and
+ * optionally the method synthetic flags / attributes as well).
+ */
+ @ParameterizedTest
+ @CsvSource({"true, true", "true, false", "false, true", "false, false"})
+ void testReadAndWrite_copyPool_changeClassVersionAndMethodSyntheticFlag(
+ final boolean upgradeVersion, final boolean changeSynthetic) {
+ ClassWriter sourceClassWriter = new ClassWriter(0);
+ sourceClassWriter.visit(
+ upgradeVersion ? Opcodes.V1_4 : Opcodes.V1_5,
+ Opcodes.ACC_ABSTRACT,
+ "C",
+ null,
+ "java/lang/Object",
+ null);
+ sourceClassWriter
+ .visitMethod(Opcodes.ACC_ABSTRACT | Opcodes.ACC_SYNTHETIC, "m", "()V", null, null)
+ .visitEnd();
+ sourceClassWriter.visitEnd();
+ ClassReader classReader = new ClassReader(sourceClassWriter.toByteArray());
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassWriter copyPoolClassWriter = new ClassWriter(classReader, 0);
+ int version = upgradeVersion ? Opcodes.V1_5 : Opcodes.V1_4;
+ int access = changeSynthetic ? Opcodes.ACC_SYNTHETIC : 0;
+
+ classReader.accept(
+ new ChangeVersionAdapter(new ChangeAccessAdapter(classWriter, access), version), 0);
+ classReader.accept(
+ new ChangeVersionAdapter(new ChangeAccessAdapter(copyPoolClassWriter, access), version), 0);
+
+ assertEquals(
+ new ClassFile(classWriter.toByteArray()), new ClassFile(copyPoolClassWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> class adapter -> ClassWriter chain gives the same result with or
+ * without the copy pool option, and a class adapter that changes the method descriptors.
+ */
+ @Test
+ void testReadAndWrite_copyPool_changeMethodDescriptor() {
+ ClassWriter sourceClassWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ sourceClassWriter.visit(
+ Opcodes.V1_7, Opcodes.ACC_ABSTRACT, "C", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ sourceClassWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+ sourceClassWriter.visitEnd();
+ ClassReader classReader = new ClassReader(sourceClassWriter.toByteArray());
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ ClassWriter copyPoolClassWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
+
+ classReader.accept(new AddParameterAdapter(classWriter), 0);
+ classReader.accept(new AddParameterAdapter(copyPoolClassWriter), 0);
+
+ assertEquals(
+ new ClassFile(classWriter.toByteArray()), new ClassFile(copyPoolClassWriter.toByteArray()));
+ }
+
+ /** Test that classes with only visible or only invisible annotations can be read correctly. */
+ @ParameterizedTest
+ @ValueSource(strings = {"true", "false"})
+ void testReadAndWrite_removeAnnotations(final boolean visibilityValue) {
+ ClassWriter classWriter = new ClassWriter(0);
+ new ClassReader(PrecompiledClass.JDK8_ALL_STRUCTURES.getBytes())
+ .accept(new RemoveAnnotationAdapter(classWriter, visibilityValue), 0);
+ byte[] classFile = classWriter.toByteArray();
+ ClassWriter newClassWriter = new ClassWriter(0);
+
+ new ClassReader(classFile)
+ .accept(new RemoveAnnotationAdapter(newClassWriter, visibilityValue), 0);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(newClassWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that optional module data (ModulePackage, ModuleMainClass, etc) can be removed with a
+ * ClassReader -> class adapter -> ClassWriter chain.
+ */
+ @Test
+ void testReadAndWrite_removeOptionalModuleData() {
+ byte[] classFile = PrecompiledClass.JDK9_MODULE.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassVisitor classVisitor =
+ new ClassVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classWriter) {
+
+ @Override
+ public ModuleVisitor visitModule(
+ final String name, final int access, final String version) {
+ return new ModuleVisitor(api, super.visitModule(name, access, version)) {
+
+ @Override
+ public void visitMainClass(final String mainClass) {}
+
+ @Override
+ public void visitPackage(final String packaze) {}
+
+ @Override
+ public void visitRequire(
+ final String module, final int access, final String version) {
+ super.visitRequire(module, access, null);
+ }
+
+ @Override
+ public void visitExport(
+ final String packaze, final int access, final String... modules) {
+ super.visitExport(packaze, access, (String[]) null);
+ }
+
+ @Override
+ public void visitOpen(
+ final String packaze, final int access, final String... modules) {
+ super.visitOpen(packaze, access, (String[]) null);
+ }
+ };
+ }
+ };
+
+ classReader.accept(classVisitor, null, 0);
+
+ String classDump = new ClassFile(classWriter.toByteArray()).toString();
+ assertFalse(classDump.contains("ModulePackage"));
+ assertFalse(classDump.contains("ModuleMainClass"));
+ }
+
+ static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ private static class AnnotationAdapter extends AnnotationVisitor {
+
+ AnnotationAdapter(final int api, final AnnotationVisitor annotationVisitor) {
+ super(api, annotationVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ return new AnnotationAdapter(api, super.visitAnnotation(name, descriptor));
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ return new AnnotationAdapter(api, super.visitArray(name));
+ }
+ }
+
+ private static class ClassAdapter extends ClassVisitor {
+
+ ClassAdapter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new AnnotationAdapter(api, super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return new FieldAdapter(api, super.visitField(access, name, descriptor, signature, value));
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodAdapter(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions));
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ return new ModuleVisitor(api, super.visitModule(name, access, version)) {};
+ }
+ }
+
+ private static class FieldAdapter extends FieldVisitor {
+
+ FieldAdapter(final int api, final FieldVisitor fieldVisitor) {
+ super(api, fieldVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new AnnotationAdapter(api, super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+ }
+
+ private static class MethodAdapter extends MethodVisitor {
+
+ MethodAdapter(final int api, final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new AnnotationAdapter(api, super.visitAnnotationDefault());
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ return new AnnotationAdapter(api, super.visitAnnotation(descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitParameterAnnotation(parameter, descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitInsnAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api, super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible));
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ return new AnnotationAdapter(
+ api,
+ super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible));
+ }
+ }
+
+ private static class ChangeExceptionAdapter extends ClassVisitor {
+
+ ChangeExceptionAdapter(final ClassVisitor classVisitor) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ if (exceptions != null && exceptions.length > 0) {
+ exceptions[0] = "java/lang/Throwable";
+ }
+ return super.visitMethod(access, name, descriptor, signature, exceptions);
+ }
+ }
+
+ private static class ChangeVersionAdapter extends ClassVisitor {
+
+ private final int newVersion;
+
+ ChangeVersionAdapter(final ClassVisitor classVisitor, final int newVersion) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ this.newVersion = newVersion;
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ super.visit(newVersion, access, name, signature, superName, interfaces);
+ }
+ }
+
+ private static class ChangeAccessAdapter extends ClassVisitor {
+
+ private final int accessFlags;
+
+ ChangeAccessAdapter(final ClassVisitor classVisitor, final int accessFlags) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ this.accessFlags = accessFlags;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return super.visitMethod(access ^ accessFlags, name, descriptor, signature, exceptions);
+ }
+ }
+
+ /** A class visitor which removes either all visible or all invisible [type] annotations. */
+ private static class RemoveAnnotationAdapter extends ClassVisitor {
+
+ private final boolean visibilityValue;
+
+ RemoveAnnotationAdapter(final ClassVisitor classVisitor, final boolean visibilityValue) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ this.visibilityValue = visibilityValue;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ return new FieldVisitor(api, super.visitField(access, name, descriptor, signature, value)) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+ };
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitAnnotation(descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitParameterAnnotation(parameter, descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ if (visible == visibilityValue) {
+ return null;
+ }
+ return super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible);
+ }
+ };
+ }
+ }
+
+ /** A class visitor which adds a parameter to the declared method descriptors. */
+ private static class AddParameterAdapter extends ClassVisitor {
+
+ public AddParameterAdapter(final ClassVisitor classVisitor) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ List<Type> argumentTypes = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(descriptor)));
+ argumentTypes.add(Type.INT_TYPE);
+ Type returnType = Type.getReturnType(descriptor);
+ return super.visitMethod(
+ access,
+ name,
+ Type.getMethodDescriptor(returnType, argumentTypes.toArray(new Type[0])),
+ signature,
+ exceptions);
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ClassWriterComputeMaxsTest.java b/asm/src/test/java/org/objectweb/asm/ClassWriterComputeMaxsTest.java
new file mode 100644
index 00000000..7e92d457
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ClassWriterComputeMaxsTest.java
@@ -0,0 +1,1198 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.concurrent.atomic.AtomicReference;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * ClassWriter unit tests for COMPUTE_MAXS option with JSR instructions.
+ *
+ * @author Eric Bruneton
+ */
+class ClassWriterComputeMaxsTest {
+
+ // Some local variable numbers used in tests.
+ private static final int LOCAL1 = 1;
+ private static final int LOCAL2 = 2;
+ private static final int LOCAL3 = 3;
+ private static final int LOCAL4 = 4;
+ private static final int LOCAL5 = 5;
+
+ // Labels used to generate test cases.
+ private final Label label0 = new Label();
+ private final Label label1 = new Label();
+ private final Label label2 = new Label();
+ private final Label label3 = new Label();
+ private final Label label4 = new Label();
+ private final Label label5 = new Label();
+ private final Label label6 = new Label();
+ private final Label label7 = new Label();
+ private final Label label8 = new Label();
+ private final Label label9 = new Label();
+ private final Label label10 = new Label();
+ private final Label label11 = new Label();
+ private final Label label12 = new Label();
+
+ /**
+ * Tests a method which has the most basic <code>try{}finally{}</code> form imaginable. That is,
+ * repeated one or more times:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * a--;
+ * }
+ * // ... same try {} finally {} repeated 0 or more times ...
+ * }
+ * </pre>
+ */
+ @ParameterizedTest
+ @ValueSource(ints = {1, 31, 32, 33})
+ void testVisitMaxs_basic(final int numSubroutines) {
+ TestCaseBuilder testCase = new TestCaseBuilder();
+ for (int i = 0; i < numSubroutines; ++i) {
+ Label k0 = new Label();
+ Label k1 = new Label();
+ Label k2 = new Label();
+ Label k3 = new Label();
+ Label k4 = new Label();
+ testCase
+ .iconst_0() // N0
+ .istore(1)
+ // Body of try block.
+ .label(k0) // N2
+ .iinc(1, 1)
+ .go(k3)
+ // Exception handler.
+ .label(k1) // N8
+ .astore(3)
+ .jsr(k2)
+ .aload(3) // N12
+ .athrow()
+ // Subroutine.
+ .label(k2) // N14
+ .astore(2)
+ .iinc(1, -1)
+ .push()
+ .push()
+ .ret(2)
+ // Non-exceptional exit from try block.
+ .label(k3) // N22
+ .jsr(k2)
+ .push() // N25
+ .push()
+ .label(k4) // N27
+ .vreturn()
+ .trycatch(k0, k1, k1)
+ .trycatch(k3, k4, k1);
+ }
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(4, methodInfo.maxStack);
+ assertEquals(4, methodInfo.maxLocals);
+ if (numSubroutines == 1) {
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N22,N8",
+ "N8=N14",
+ "N12=",
+ "N14=N12,N25",
+ "N22=N14,N8",
+ "N25=N27,N8",
+ "N27=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ }
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests a method which has an if/else-if w/in the finally clause. More specifically:
+ *
+ * <pre>
+ * public void a() {
+ * int a = 0;
+ * try {
+ * a++;
+ * } finally {
+ * if (a == 0) {
+ * a += 2;
+ * } else {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_ifElseInFinally() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // Body of try block.
+ .label(label0) // N2
+ .iinc(1, 1)
+ .go(label5)
+ // Exception handler.
+ .label(label1) // N8
+ .astore(3)
+ .jsr(label2)
+ .push() // N12
+ .push()
+ .aload(3)
+ .athrow()
+ // Subroutine.
+ .label(label2) // N16
+ .astore(2)
+ .push()
+ .push()
+ .iload(1)
+ .ifne(label3)
+ .iinc(1, 2)
+ .go(label4)
+ .label(label3) // N29
+ .iinc(1, 3)
+ .label(label4) // N32, common exit.
+ .ret(2)
+ // Non-exceptional exit from try block.
+ .label(label5) // N34
+ .jsr(label2)
+ .label(label6) // N37
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label5, label6, label1);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(5, methodInfo.maxStack);
+ assertEquals(4, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N34,N8",
+ "N8=N16",
+ "N12=",
+ "N16=N29,N32",
+ "N29=N32",
+ "N32=N37,N12",
+ "N34=N16,N8",
+ "N37=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests a simple nested finally. More specifically:
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * try {
+ * a += 1;
+ * } finally {
+ * try {
+ * a += 2;
+ * } finally {
+ * a += 3;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_simpleNestedFinally() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // Body of try block.
+ .label(label0) // N2
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label5) // N8
+ // First exception handler.
+ .label(label1) // N11
+ .astore(4)
+ .jsr(label2)
+ .aload(4) // N16
+ .athrow()
+ // First subroutine.
+ .label(label2) // N19
+ .astore(2)
+ .iinc(1, 2)
+ .jsr(label4)
+ .push() // N26
+ .push()
+ .ret(2)
+ // Second exception handler.
+ .label(label3) // N30
+ .astore(5)
+ .jsr(label4)
+ .aload(5) // N35
+ .athrow()
+ // Second subroutine.
+ .label(label4) // N38
+ .astore(3)
+ .push()
+ .push()
+ .iinc(1, 3)
+ .ret(3)
+ // On normal exit, try block jumps here.
+ .label(label5) // N46
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label2, label3, label3);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(5, methodInfo.maxStack);
+ assertEquals(6, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N11,N19",
+ "N8=N11,N46",
+ "N11=N19",
+ "N16=",
+ "N19=N30,N38",
+ "N26=N16,N30,N8",
+ "N30=N38",
+ "N35=",
+ "N38=N26,N35",
+ "N46=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead.
+ *
+ * <p>We structure this as a try/finally with a break in the finally. Because the while loop is
+ * infinite, it's clear from the byte code that the only path which reaches the RETURN instruction
+ * is through the subroutine.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (true) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_subroutineWithNoRet() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // While loop header/try block.
+ .label(label0) // N2
+ .iinc(1, 1)
+ .jsr(label2)
+ .go(label3) // N8
+ // Implicit catch block.
+ .label(label1) // N11
+ .astore(2)
+ .jsr(label2)
+ .push() // N15
+ .push()
+ .aload(2)
+ .athrow()
+ // Subroutine which does not return.
+ .label(label2) // N19
+ .astore(3)
+ .iinc(1, 2)
+ .go(label4)
+ // End of the loop, goes back to the top.
+ .label(label3) // N26
+ .go(label0)
+ .label(label4) // N29
+ .vreturn()
+ .trycatch(label0, label1, label1);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(1, methodInfo.maxStack);
+ assertEquals(4, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2", "N2=N11,N19", "N8=N11,N26", "N11=N19", "N15=", "N19=N29", "N26=N2", "N29=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but ends in a "return" instead.
+ *
+ * <pre>
+ * aconst_null
+ * jsr l0
+ * l0:
+ * astore 0
+ * astore 0
+ * return
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_subroutineWithNoRet2() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .aconst_null() // N0
+ .jsr(label0)
+ .nop() // N4
+ .label(label0) // N5
+ .astore(0)
+ .astore(0)
+ .vreturn()
+ .label(label1) // N8
+ .localVariable("i", "I", null, label0, label1, 1);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(2, methodInfo.maxStack);
+ assertEquals(2, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph("N0=N5", "N4=N5", "N5=", "N8=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * This tests a subroutine which has no ret statement, but instead exits implicitly by branching
+ * to code which is not part of the subroutine. (Sadly, this is legal)
+ *
+ * <p>We structure this as a try/finally in a loop with a break in the finally. The loop is not
+ * trivially infinite, so the RETURN statement is reachable both from the JSR subroutine and from
+ * the main entry point.
+ *
+ * <pre>
+ * public void a1() {
+ * int a = 0;
+ * while (null == null) {
+ * try {
+ * a += 1;
+ * } finally {
+ * a += 2;
+ * break;
+ * }
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_implicitExit() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // While loop header.
+ .label(label0) // N2
+ .aconst_null()
+ .ifnonnull(label5)
+ // Try block.
+ .label(label1) // N6
+ .iinc(1, 1)
+ .jsr(label3)
+ .go(label4) // N12
+ // Implicit catch block.
+ .label(label2) // N15
+ .astore(2)
+ .jsr(label3)
+ .aload(2) // N19
+ .push()
+ .push()
+ .athrow()
+ // Subroutine which does not return.
+ .label(label3) // N23
+ .astore(3)
+ .iinc(1, 2)
+ .go(label5)
+ // End of the loop, goes back to the top.
+ .label(label4) // N30
+ .go(label1)
+ .label(label5) // N33
+ .vreturn()
+ .trycatch(label1, label2, label2);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(1, methodInfo.maxStack);
+ assertEquals(4, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N6,N33",
+ "N6=N23,N15",
+ "N12=N30,N15",
+ "N15=N23",
+ "N19=",
+ "N23=N33",
+ "N30=N6",
+ "N33=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine.
+ * Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(boolean b) {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>This example is from the paper, "Subroutine Inlining and Bytecode Abstraction to Simplify
+ * Static and Dynamic Analysis" by Cyrille Artho and Armin Biere.
+ */
+ @Test
+ void testVisitMaxs_implicitExitToAnotherSubroutine() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // First try.
+ .label(label0) // N2
+ .jsr(label2)
+ .vreturn() // N5
+ // Exception handler for first try.
+ .label(label1) // N6
+ .astore(LOCAL2)
+ .jsr(label2)
+ .push() // N10
+ .push()
+ .aload(LOCAL2)
+ .athrow()
+ // First finally handler.
+ .label(label2) // N14
+ .astore(LOCAL4)
+ .push()
+ .push()
+ .go(label6)
+ // Body of while loop, also second try.
+ .label(label3) // N21
+ .jsr(label5)
+ .vreturn() // N24
+ // Exception handler for second try.
+ .label(label4) // N25
+ .astore(LOCAL3)
+ .push()
+ .push()
+ .jsr(label5)
+ .aload(LOCAL3) // N31
+ .athrow()
+ // Second finally handler.
+ .label(label5) // N33
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label7)
+ .ret(LOCAL5)
+ // Test for the while loop.
+ .label(label6) // N41
+ .iload(LOCAL1)
+ .ifne(label3) // falls through to X.
+ // Exit from finally block.
+ .label(label7) // N45
+ .ret(LOCAL4)
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label4);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(5, methodInfo.maxStack);
+ assertEquals(6, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N6,N14",
+ "N5=N6",
+ "N6=N14",
+ "N10=",
+ "N14=N41",
+ "N21=N25,N33",
+ "N24=N25",
+ "N25=N33",
+ "N31=",
+ "N33=N31,N45,N24",
+ "N41=N45,N21",
+ "N45=N5,N10");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ @Test
+ void testVisitMaxs_implicitExitToAnotherSubroutine2() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ .jsr(label0)
+ .vreturn() // N5
+ .label(label0) // N6
+ .astore(2)
+ .jsr(label1)
+ .go(label2) // N10
+ .label(label1) // N13
+ .astore(3)
+ .iload(1)
+ .ifne(label2)
+ .ret(3)
+ .label(label2) // N20
+ .ret(2);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(1, methodInfo.maxStack);
+ assertEquals(4, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph("N0=N6", "N5=", "N6=N13", "N10=N20", "N13=N20,N10", "N20=N5");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * This tests a simple subroutine where the control flow jumps back and forth between the
+ * subroutine and the caller.
+ *
+ * <p>This would not normally be produced by a Java compiler.
+ */
+ @Test
+ void testVisitMaxs_interleavedCode() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ .jsr(label0)
+ .go(label1) // N5
+ // Subroutine 1.
+ .label(label0) // N8
+ .astore(2)
+ .iinc(1, 1)
+ .go(label2)
+ // Second part of main subroutine.
+ .label(label1) // N15
+ .iinc(1, 2)
+ .go(label3)
+ // Second part of subroutine 1.
+ .label(label2) // N21
+ .iinc(1, 4)
+ .push()
+ .push()
+ .ret(2)
+ // Third part of main subroutine.
+ .label(label3) // N28
+ .push()
+ .push()
+ .vreturn();
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(4, methodInfo.maxStack);
+ assertEquals(3, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph("N0=N8", "N5=N15", "N8=N21", "N15=N28", "N21=N5", "N28=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests a nested try/finally with implicit exit from one subroutine to the other subroutine, and
+ * with a surrounding try/catch thrown in the mix. Equivalent to the following java code:
+ *
+ * <pre>
+ * void m(int b) {
+ * try {
+ * try {
+ * return;
+ * } finally {
+ * while (b) {
+ * try {
+ * return;
+ * } finally {
+ * // NOTE --- this break avoids the second return above (weird)
+ * if (b) {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ * } catch (Exception e) {
+ * b += 3;
+ * return;
+ * }
+ * }
+ * </pre>
+ */
+ @Test
+ void testVisitMaxs_implicitExitInTryCatch() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .iconst_0() // N0
+ .istore(1)
+ // First try.
+ .label(label0) // N2
+ .jsr(label2)
+ .vreturn() // N5
+ // Exception handler for first try.
+ .label(label1) // N6
+ .astore(LOCAL2)
+ .jsr(label2)
+ .aload(LOCAL2) // N10
+ .athrow()
+ // First finally handler.
+ .label(label2) // N12
+ .astore(LOCAL4)
+ .go(label6)
+ // Body of while loop, also second try.
+ .label(label3) // N17
+ .jsr(label5)
+ .push() // N20
+ .push()
+ .vreturn()
+ // Exception handler for second try.
+ .label(label4) // N23
+ .astore(LOCAL3)
+ .jsr(label5)
+ .aload(LOCAL3) // N27
+ .athrow()
+ // Second finally handler.
+ .label(label5) // N29
+ .astore(LOCAL5)
+ .iload(LOCAL1)
+ .ifne(label7)
+ .push()
+ .push()
+ .ret(LOCAL5)
+ // Test for the while loop.
+ .label(label6) // N39
+ .iload(LOCAL1)
+ .ifne(label3) // Falls through.
+ // Exit from finally block.
+ .label(label7) // N43
+ .ret(LOCAL4)
+ // Outermost catch.
+ .label(label8) // N45
+ .iinc(LOCAL1, 3)
+ .vreturn()
+ .trycatch(label0, label1, label1)
+ .trycatch(label3, label4, label4)
+ .trycatch(label0, label8, label8);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(4, methodInfo.maxStack);
+ assertEquals(6, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N2",
+ "N2=N6,N45,N12",
+ "N5=N6,N45",
+ "N6=N45,N12",
+ "N10=N45",
+ "N12=N39,N45",
+ "N17=N23,N45,N29",
+ "N20=N23,N45",
+ "N23=N45,N29",
+ "N27=N45",
+ "N29=N43,N45,N20,N27",
+ "N39=N43,N45,N17",
+ "N43=N45,N5,N10",
+ "N45=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests an example coming from distilled down version of
+ * com/sun/corba/ee/impl/protocol/CorbaClientDelegateImpl from GlassFish 2. See issue #317823.
+ */
+ @Test
+ void testVisitMaxs_glassFish2CorbaClientDelegateImplExample() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .label(label0) // N0
+ .jsr(label4)
+ .label(label1) // N3
+ .go(label5)
+ .label(label2) // N6
+ .pop()
+ .jsr(label4)
+ .label(label3) // N10
+ .aconst_null()
+ .athrow()
+ .label(label4) // N12
+ .astore(1)
+ .ret(1)
+ .label(label5) // N15
+ .aconst_null()
+ .aconst_null()
+ .aconst_null()
+ .pop()
+ .pop()
+ .pop()
+ .label(label6) // N21
+ .go(label8)
+ .label(label7) // N24
+ .pop()
+ .go(label8)
+ .aconst_null()
+ .athrow()
+ .label(label8) // N30
+ .iconst_0()
+ .ifne(label0)
+ .jsr(label12)
+ .label(label9) // N37
+ .vreturn()
+ .label(label10) // N38
+ .pop()
+ .jsr(label12)
+ .label(label11) // N42
+ .aconst_null()
+ .athrow()
+ .label(label12) // N44
+ .astore(2)
+ .ret(2)
+ .trycatch(label0, label1, label2)
+ .trycatch(label2, label3, label2)
+ .trycatch(label0, label6, label7)
+ .trycatch(label0, label9, label10)
+ .trycatch(label10, label11, label10);
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(3, methodInfo.maxStack);
+ assertEquals(3, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph(
+ "N0=N6,N12,N24,N38",
+ "N3=N15,N24,N38",
+ "N6=N6,N12,N24,N38",
+ "N10=N24,N38",
+ "N12=N3,N10,N24,N38",
+ "N15=N21,N24,N38",
+ "N21=N30,N38",
+ "N24=N30,N38",
+ "N30=N0,N38,N44",
+ "N37=",
+ "N38=N38,N44",
+ "N42=",
+ "N44=N37,N42");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests a nested subroutine with implicit exit from the nested subroutine to the outer one, with
+ * the second subroutine coming first in the bytecode instructions sequence.
+ */
+ @Test
+ void testVisitMaxs_implicitExitToAnotherSubroutineInverted() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder()
+ .go(label3) // N0
+ // Second subroutine, returns to caller of first subroutine.
+ .label(label0) // N3
+ .astore(2)
+ .label(label1) // N4
+ .ret(1)
+ // First subroutine.
+ .label(label2) // N6
+ .astore(1)
+ .aload(0)
+ .ifnonnull(label1)
+ .jsr(label0) // This JSR never returns, the following code is unreachable.
+ .aconst_null() // N14
+ .aconst_null()
+ .aconst_null()
+ .vreturn()
+ // Main "subroutine".
+ .label(label3) // N18
+ .jsr(label2)
+ .label(label4) // N21
+ .vreturn();
+
+ Map<String, Set<String>> controlFlowGraph = testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(1, methodInfo.maxStack);
+ assertEquals(3, methodInfo.maxLocals);
+ Map<String, Set<String>> expectedControlFlowGraph =
+ controlFlowGraph("N0=N18", "N3=N4", "N4=N21", "N6=N3,N4", "N14=", "N18=N6", "N21=");
+ assertEquals(expectedControlFlowGraph, controlFlowGraph);
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ /**
+ * Tests computing the maximum stack size from the existing stack map frames and the instructions
+ * in between, when dead code is present.
+ */
+ @Test
+ void testVisitMaxs_framesWithDeadCode() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder(Opcodes.V1_7)
+ .vreturn()
+ // With the default compute maxs algorithm, this dead code block is not considered for
+ // the maximum stack size, which works fine for classes up to V1_6. Starting with V1_7,
+ // stack map frames are mandatory, even for dead code, and the maximum stack size must
+ // take dead code into account. Hopefully it can be computed from the stack map frames,
+ // and the instructions in between (without any control flow graph construction or
+ // algorithm).
+ .label(label0)
+ .frame(Opcodes.F_SAME, 0, null, 0, null)
+ .aconst_null()
+ .vreturn();
+
+ testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(1, methodInfo.maxStack);
+ assertEquals(1, methodInfo.maxLocals);
+ }
+
+ @Test
+ void testVisitMaxs_frameWithLong() {
+ TestCaseBuilder testCase =
+ new TestCaseBuilder(Opcodes.V1_7)
+ .push2()
+ .go(label0)
+ .label(label0)
+ .frame(Opcodes.F_NEW, 0, null, 1, new Object[] {Opcodes.LONG})
+ .aconst_null()
+ .vreturn();
+
+ testCase.visitMaxs();
+ byte[] classFile = testCase.build();
+
+ MethodInfo methodInfo = readMaxStackAndLocals(classFile);
+ assertEquals(3, methodInfo.maxStack);
+ assertEquals(1, methodInfo.maxLocals);
+ }
+
+ private static MethodInfo readMaxStackAndLocals(final byte[] classFile) {
+ AtomicReference<MethodInfo> methodInfo = new AtomicReference<>();
+ ClassReader classReader = new ClassReader(classFile);
+ classReader.accept(
+ new ClassVisitor(Opcodes.ASM5) {
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ if (name.equals("m")) {
+ return new MethodVisitor(Opcodes.ASM5) {
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ methodInfo.set(new MethodInfo(maxStack, maxLocals));
+ }
+ };
+ } else {
+ return null;
+ }
+ }
+ },
+ 0);
+ return methodInfo.get();
+ }
+
+ private static Map<String, Set<String>> controlFlowGraph(final String... nodes) {
+ Map<String, Set<String>> graph = new HashMap<>();
+ for (String node : nodes) {
+ StringTokenizer stringTokenizer = new StringTokenizer(node, "=,");
+ String key = stringTokenizer.nextToken();
+ Set<String> values = new HashSet<>();
+ while (stringTokenizer.hasMoreTokens()) {
+ values.add(stringTokenizer.nextToken());
+ }
+ graph.put(key, values);
+ }
+ return graph;
+ }
+
+ private static class MethodInfo {
+
+ public final int maxStack;
+ public final int maxLocals;
+
+ public MethodInfo(final int maxStack, final int maxLocals) {
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ }
+ }
+
+ private static final class TestCaseBuilder {
+
+ private final ClassWriter classWriter;
+ private final MethodVisitor methodVisitor;
+ private final Label start;
+
+ TestCaseBuilder() {
+ this(Opcodes.V1_1);
+ }
+
+ TestCaseBuilder(final int classVersion) {
+ classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ classWriter.visit(classVersion, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ MethodVisitor constructor =
+ classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ constructor.visitCode();
+ constructor.visitVarInsn(Opcodes.ALOAD, 0);
+ constructor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ constructor.visitInsn(Opcodes.RETURN);
+ constructor.visitMaxs(1, 1);
+ constructor.visitEnd();
+ methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ start = new Label();
+ label(start);
+ }
+
+ TestCaseBuilder nop() {
+ methodVisitor.visitInsn(Opcodes.NOP);
+ return this;
+ }
+
+ TestCaseBuilder push() {
+ methodVisitor.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ TestCaseBuilder push2() {
+ methodVisitor.visitInsn(Opcodes.LCONST_0);
+ return this;
+ }
+
+ TestCaseBuilder pop() {
+ methodVisitor.visitInsn(Opcodes.POP);
+ return this;
+ }
+
+ TestCaseBuilder iconst_0() {
+ methodVisitor.visitInsn(Opcodes.ICONST_0);
+ return this;
+ }
+
+ TestCaseBuilder istore(final int varIndex) {
+ methodVisitor.visitVarInsn(Opcodes.ISTORE, varIndex);
+ return this;
+ }
+
+ TestCaseBuilder aload(final int varIndex) {
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, varIndex);
+ return this;
+ }
+
+ TestCaseBuilder iload(final int varIndex) {
+ methodVisitor.visitVarInsn(Opcodes.ILOAD, varIndex);
+ return this;
+ }
+
+ TestCaseBuilder astore(final int varIndex) {
+ methodVisitor.visitVarInsn(Opcodes.ASTORE, varIndex);
+ return this;
+ }
+
+ TestCaseBuilder ret(final int varIndex) {
+ methodVisitor.visitVarInsn(Opcodes.RET, varIndex);
+ return this;
+ }
+
+ TestCaseBuilder athrow() {
+ methodVisitor.visitInsn(Opcodes.ATHROW);
+ return this;
+ }
+
+ TestCaseBuilder aconst_null() {
+ methodVisitor.visitInsn(Opcodes.ACONST_NULL);
+ return this;
+ }
+
+ TestCaseBuilder vreturn() {
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ return this;
+ }
+
+ TestCaseBuilder label(final Label label) {
+ methodVisitor.visitLabel(label);
+ return this;
+ }
+
+ TestCaseBuilder iinc(final int varIndex, final int increment) {
+ methodVisitor.visitIincInsn(varIndex, increment);
+ return this;
+ }
+
+ TestCaseBuilder frame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ methodVisitor.visitFrame(type, numLocal, local, numStack, stack);
+ return this;
+ }
+
+ TestCaseBuilder go(final Label label) {
+ methodVisitor.visitJumpInsn(Opcodes.GOTO, label);
+ return this;
+ }
+
+ TestCaseBuilder jsr(final Label label) {
+ methodVisitor.visitJumpInsn(Opcodes.JSR, label);
+ return this;
+ }
+
+ TestCaseBuilder ifnonnull(final Label label) {
+ methodVisitor.visitJumpInsn(Opcodes.IFNONNULL, label);
+ return this;
+ }
+
+ TestCaseBuilder ifne(final Label label) {
+ methodVisitor.visitJumpInsn(Opcodes.IFNE, label);
+ return this;
+ }
+
+ TestCaseBuilder trycatch(final Label start, final Label end, final Label handler) {
+ methodVisitor.visitTryCatchBlock(start, end, handler, null);
+ return this;
+ }
+
+ TestCaseBuilder localVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ methodVisitor.visitLocalVariable(name, descriptor, signature, start, end, index);
+ return this;
+ }
+
+ /**
+ * Calls the visitMaxs method and returns the computed control flow graph.
+ *
+ * @return the computed control flow graph.
+ */
+ Map<String, Set<String>> visitMaxs() {
+ methodVisitor.visitMaxs(0, 0);
+
+ Map<String, Set<String>> graph = new HashMap<>();
+ Label currentLabel = start;
+ while (currentLabel != null) {
+ String key = "N" + currentLabel.getOffset();
+ Set<String> value = new HashSet<>();
+ Edge outgoingEdge = currentLabel.outgoingEdges;
+ if ((currentLabel.flags & Label.FLAG_SUBROUTINE_CALLER) != 0) {
+ // Ignore the first outgoing edge of the basic blocks ending with a jsr: these are virtual
+ // edges which lead to the instruction just after the jsr, and do not correspond to a
+ // possible execution path (see {@link #visitJumpInsn} and
+ // {@link Label#FLAG_SUBROUTINE_CALLER}).
+ assertNotNull(outgoingEdge);
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ while (outgoingEdge != null) {
+ value.add("N" + outgoingEdge.successor.getOffset());
+ outgoingEdge = outgoingEdge.nextEdge;
+ }
+ graph.put(key, value);
+ currentLabel = currentLabel.nextBasicBlock;
+ }
+ return graph;
+ }
+
+ byte[] build() {
+ methodVisitor.visitEnd();
+ classWriter.visitEnd();
+ return classWriter.toByteArray();
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
new file mode 100644
index 00000000..fb9034ed
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
@@ -0,0 +1,1068 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static java.util.stream.Collectors.toSet;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.ClassFile;
+
+/**
+ * Unit tests for {@link ClassWriter}.
+ *
+ * @author Eric Bruneton
+ */
+class ClassWriterTest extends AsmTest {
+
+ /**
+ * Tests that the non-static fields of ClassWriter are the expected ones. This test is designed to
+ * fail each time new fields are added to ClassWriter, and serves as a reminder to update the
+ * field reset logic in {@link ClassWriter#replaceAsmInstructions()}, if needed, each time a new
+ * field is added.
+ */
+ @Test
+ void testInstanceFields() {
+ Set<String> actualFields =
+ Arrays.stream(ClassWriter.class.getDeclaredFields())
+ .filter(field -> !Modifier.isStatic(field.getModifiers()))
+ .map(Field::getName)
+ .collect(toSet());
+
+ Set<String> expectedFields =
+ new HashSet<String>(
+ Arrays.asList(
+ "flags",
+ "version",
+ "symbolTable",
+ "accessFlags",
+ "thisClass",
+ "superClass",
+ "interfaceCount",
+ "interfaces",
+ "firstField",
+ "lastField",
+ "firstMethod",
+ "lastMethod",
+ "numberOfInnerClasses",
+ "innerClasses",
+ "enclosingClassIndex",
+ "enclosingMethodIndex",
+ "signatureIndex",
+ "sourceFileIndex",
+ "debugExtension",
+ "lastRuntimeVisibleAnnotation",
+ "lastRuntimeInvisibleAnnotation",
+ "lastRuntimeVisibleTypeAnnotation",
+ "lastRuntimeInvisibleTypeAnnotation",
+ "moduleWriter",
+ "nestHostClassIndex",
+ "numberOfNestMemberClasses",
+ "nestMemberClasses",
+ "numberOfPermittedSubclasses",
+ "permittedSubclasses",
+ "firstRecordComponent",
+ "lastRecordComponent",
+ "firstAttribute",
+ "compute"));
+ // IMPORTANT: if this fails, update the string list AND update the logic that resets the
+ // ClassWriter fields in ClassWriter.toByteArray(), if needed (this logic is used to do a
+ // ClassReader->ClassWriter round trip to remove the ASM specific instructions due to large
+ // forward jumps).
+ assertEquals(expectedFields, actualFields);
+ }
+
+ /**
+ * Checks that all the ClassVisitor methods are overridden by ClassWriter and are final.
+ * ClassWriter does not take an api version as constructor argument. Therefore, backward
+ * compatibility of user subclasses overriding some visit methods of ClassWriter would not be
+ * possible to ensure. To prevent this, the ClassWriter visit methods must be final.
+ */
+ @Test
+ void testVisitMethods_final() {
+ ArrayList<Method> publicClassVisitorMethods = new ArrayList<>();
+ for (Method classVisitorMethod : ClassVisitor.class.getDeclaredMethods()) {
+ int modifiers = classVisitorMethod.getModifiers();
+ if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
+ publicClassVisitorMethods.add(classVisitorMethod);
+ }
+ }
+
+ for (Method classVisitorMethod : publicClassVisitorMethods) {
+ try {
+ Method classWriterMethod =
+ ClassWriter.class.getMethod(
+ classVisitorMethod.getName(), classVisitorMethod.getParameterTypes());
+ if (!classWriterMethod.getName().equals("getDelegate")) {
+ assertTrue(
+ Modifier.isFinal(classWriterMethod.getModifiers()), classWriterMethod + " is final");
+ }
+ } catch (NoSuchMethodException e) {
+ fail("ClassWriter must override " + classVisitorMethod);
+ }
+ }
+ }
+
+ @Test
+ void testNewConst() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newConst(Boolean.FALSE);
+ classWriter.newConst(Byte.valueOf((byte) 1));
+ classWriter.newConst(Character.valueOf('2'));
+ classWriter.newConst(Short.valueOf((short) 3));
+
+ String constantPoolDump = getConstantPoolDump(classWriter);
+ assertTrue(constantPoolDump.contains("constant_pool: 0"));
+ assertTrue(constantPoolDump.contains("constant_pool: 1"));
+ assertTrue(constantPoolDump.contains("constant_pool: 50"));
+ assertTrue(constantPoolDump.contains("constant_pool: 3"));
+ }
+
+ @Test
+ void testNewConst_illegalArgument() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ Executable newConst = () -> classWriter.newConst(new Object());
+
+ Exception exception = assertThrows(IllegalArgumentException.class, newConst);
+ assertTrue(exception.getMessage().matches("value java\\.lang\\.Object@.*"));
+ }
+
+ @Test
+ void testNewUtf8() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newUTF8("A");
+
+ assertTrue(getConstantPoolDump(classWriter).contains("constant_pool: A"));
+ }
+
+ @Test
+ void testNewClass() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newClass("A");
+
+ assertTrue(getConstantPoolDump(classWriter).contains("constant_pool: ConstantClassInfo A"));
+ }
+
+ @Test
+ void testNewMethodType() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newMethodType("()V");
+
+ assertTrue(
+ getConstantPoolDump(classWriter).contains("constant_pool: ConstantMethodTypeInfo ()V"));
+ }
+
+ @Test
+ void testNewModule() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newModule("A");
+
+ assertTrue(getConstantPoolDump(classWriter).contains("constant_pool: ConstantModuleInfo A"));
+ }
+
+ @Test
+ void testNewPackage() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newPackage("A");
+
+ assertTrue(getConstantPoolDump(classWriter).contains("constant_pool: ConstantPackageInfo A"));
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedNewHandle() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newHandle(Opcodes.H_GETFIELD, "A", "h", "I");
+
+ assertTrue(
+ getConstantPoolDump(classWriter)
+ .contains("constant_pool: ConstantMethodHandleInfo 1.ConstantFieldRefInfo A.hI"));
+ }
+
+ @Test
+ void testNewHandle() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newHandle(Opcodes.H_GETFIELD, "A", "h", "I", false);
+
+ assertTrue(
+ getConstantPoolDump(classWriter)
+ .contains("constant_pool: ConstantMethodHandleInfo 1.ConstantFieldRefInfo A.hI"));
+ }
+
+ @Test
+ void testNewConstantDynamic() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newConstantDynamic(
+ "m", "Ljava/lang/String;", new Handle(Opcodes.H_INVOKESTATIC, "A", "m", "()V", false));
+
+ String constantPoolDump = getConstantPoolDump(classWriter);
+ assertTrue(
+ constantPoolDump.contains("constant_pool: ConstantDynamicInfo 0.mLjava/lang/String;"));
+ assertTrue(
+ constantPoolDump.contains(
+ "constant_pool: ConstantMethodHandleInfo 6.ConstantMethodRefInfo A.m()V"));
+ assertTrue(constantPoolDump.contains("constant_pool: BootstrapMethods"));
+ }
+
+ @Test
+ void testNewInvokeDynamic() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newInvokeDynamic("m", "()V", new Handle(Opcodes.H_GETFIELD, "A", "h", "I", false));
+
+ String constantPoolDump = getConstantPoolDump(classWriter);
+ assertTrue(constantPoolDump.contains("ConstantInvokeDynamicInfo 0.m()V"));
+ assertTrue(
+ constantPoolDump.contains(
+ "constant_pool: ConstantMethodHandleInfo 1.ConstantFieldRefInfo A.hI"));
+ assertTrue(constantPoolDump.contains("constant_pool: BootstrapMethods"));
+ }
+
+ @Test
+ void testNewField() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newField("A", "f", "I");
+
+ assertTrue(
+ getConstantPoolDump(classWriter).contains("constant_pool: ConstantFieldRefInfo A.fI"));
+ }
+
+ @Test
+ void testNewMethod() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newMethod("A", "m", "()V", false);
+
+ assertTrue(
+ getConstantPoolDump(classWriter).contains("constant_pool: ConstantMethodRefInfo A.m()V"));
+ }
+
+ @Test
+ void testNewNameType() {
+ ClassWriter classWriter = newEmptyClassWriter();
+
+ classWriter.newNameType("m", "()V");
+
+ assertTrue(
+ getConstantPoolDump(classWriter).contains("constant_pool: ConstantNameAndTypeInfo m()V"));
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = {65535, 65536})
+ void testToByteArray_constantPoolSizeTooLarge(final int constantPoolCount) {
+ ClassWriter classWriter = newEmptyClassWriter();
+ int initConstantPoolCount = 5;
+ for (int i = 0; i < constantPoolCount - initConstantPoolCount; ++i) {
+ classWriter.newConst(Integer.valueOf(i));
+ }
+
+ Executable toByteArray = () -> classWriter.toByteArray();
+
+ if (constantPoolCount > 65535) {
+ ClassTooLargeException exception = assertThrows(ClassTooLargeException.class, toByteArray);
+ assertEquals("C", exception.getClassName());
+ assertEquals(constantPoolCount, exception.getConstantPoolCount());
+ assertEquals("Class too large: C", exception.getMessage());
+ } else {
+ assertDoesNotThrow(toByteArray);
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = {65535, 65536})
+ void testToByteArray_methodCodeSizeTooLarge(final int methodCodeSize) {
+ ClassWriter classWriter = newEmptyClassWriter();
+ String methodName = "m";
+ String descriptor = "()V";
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_STATIC, methodName, descriptor, null, null);
+ methodVisitor.visitCode();
+ for (int i = 0; i < methodCodeSize - 1; ++i) {
+ methodVisitor.visitInsn(Opcodes.NOP);
+ }
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ Executable toByteArray = () -> classWriter.toByteArray();
+
+ if (methodCodeSize > 65535) {
+ MethodTooLargeException exception = assertThrows(MethodTooLargeException.class, toByteArray);
+ assertEquals(methodName, exception.getMethodName());
+ assertEquals("C", exception.getClassName());
+ assertEquals(descriptor, exception.getDescriptor());
+ assertEquals(methodCodeSize, exception.getCodeSize());
+ assertEquals("Method too large: C.m ()V", exception.getMessage());
+ } else {
+ assertDoesNotThrow(toByteArray);
+ }
+ }
+
+ @Test
+ void testToByteArray_largeSourceDebugExtension() {
+ ClassWriter classWriter = newEmptyClassWriter();
+ classWriter.visitSource("Test.java", new String(new char[100000]));
+
+ classWriter.toByteArray();
+
+ assertTrue(getDump(classWriter).contains("attribute_name_index: SourceDebugExtension"));
+ }
+
+ /**
+ * Tests that the COMPUTE_MAXS option works correctly on classes with very large or deeply nested
+ * subroutines (#307600, #311642).
+ *
+ * @throws IOException if the input class file can't be read.
+ */
+ @ParameterizedTest
+ @ValueSource(strings = {"Issue307600.class", "Issue311642.class"})
+ void testToByteArray_computeMaxs_largeSubroutines(final String classFileName) throws IOException {
+ ClassReader classReader =
+ new ClassReader(Files.newInputStream(Paths.get("src/test/resources/" + classFileName)));
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ classReader.accept(classWriter, attributes(), 0);
+
+ Executable toByteArray = () -> classWriter.toByteArray();
+
+ assertDoesNotThrow(toByteArray);
+ }
+
+ @Test
+ void testToByteArray_computeFrames_mergeLongOrDouble() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "A", null, "java/lang/Object", null);
+ // Generate a default constructor, so that we can instantiate the class.
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+ // A method with a long local variable using slots 0 and 1, with an int stored in slot 1 in a
+ // branch. At the end of the method, the stack map frame should contain 'TOP' for slot 0,
+ // otherwise the class instantiation fails with a verification error.
+ methodVisitor = classWriter.visitMethod(Opcodes.ACC_STATIC, "m", "(J)V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitInsn(Opcodes.ICONST_0);
+ Label label = new Label();
+ methodVisitor.visitJumpInsn(Opcodes.IFNE, label);
+ methodVisitor.visitInsn(Opcodes.ICONST_0);
+ methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);
+ methodVisitor.visitLabel(label);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+ classWriter.visitEnd();
+
+ byte[] classFile = classWriter.toByteArray();
+
+ assertDoesNotThrow(() -> new ClassFile(classFile).newInstance());
+ }
+
+ @Test
+ void testToByteArray_computeFrames_highDimensionArrays() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "A", null, "java/lang/Object", null);
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(
+ Opcodes.ACC_STATIC,
+ "m",
+ "(I[[[[[[[[Ljava/lang/Integer;[[[[[[[[Ljava/lang/Long;)Ljava/lang/Object;",
+ null,
+ null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ILOAD, 0);
+ Label thenLabel = new Label();
+ Label endIfLabel = new Label();
+ methodVisitor.visitJumpInsn(Opcodes.IFNE, thenLabel);
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
+ methodVisitor.visitJumpInsn(Opcodes.GOTO, endIfLabel);
+ methodVisitor.visitLabel(thenLabel);
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 2);
+ // At this point the stack can contain either an 8 dimensions Integer array or an 8 dimensions
+ // Long array. The merged type computed with the COMPUTE_FRAMES option should therefore be an
+ // 8 dimensions Number array.
+ methodVisitor.visitLabel(endIfLabel);
+ methodVisitor.visitInsn(Opcodes.ARETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+ classWriter.visitEnd();
+
+ byte[] classFile = classWriter.toByteArray();
+
+ // Check that the merged frame type is correctly computed.
+ assertTrue(new ClassFile(classFile).toString().contains("[[[[[[[[Ljava/lang/Number;"));
+ }
+
+ @Test
+ void testGetCommonSuperClass() {
+ ClassWriter classWriter = new ClassWriter(0);
+
+ assertEquals(
+ "java/lang/Object",
+ classWriter.getCommonSuperClass("java/lang/Object", "java/lang/Integer"));
+ assertEquals(
+ "java/lang/Object",
+ classWriter.getCommonSuperClass("java/lang/Integer", "java/lang/Object"));
+ assertEquals(
+ "java/lang/Object",
+ classWriter.getCommonSuperClass("java/lang/Integer", "java/lang/Runnable"));
+ assertEquals(
+ "java/lang/Object",
+ classWriter.getCommonSuperClass("java/lang/Runnable", "java/lang/Integer"));
+ assertEquals(
+ "java/lang/Throwable",
+ classWriter.getCommonSuperClass(
+ "java/lang/IndexOutOfBoundsException", "java/lang/AssertionError"));
+ Exception exception =
+ assertThrows(
+ TypeNotPresentException.class,
+ () -> classWriter.getCommonSuperClass("-", "java/lang/Object"));
+ assertEquals("Type - not present", exception.getMessage());
+ exception =
+ assertThrows(
+ TypeNotPresentException.class,
+ () -> classWriter.getCommonSuperClass("java/lang/Object", "-"));
+ assertEquals("Type - not present", exception.getMessage());
+ }
+
+ /** Tests that a ClassReader -> ClassWriter transform leaves classes unchanged. */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classWriter, attributes(), 0);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> ClassWriter transform with the SKIP_CODE option produces a valid
+ * class.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_skipCode(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classWriter, attributes(), ClassReader.SKIP_CODE);
+
+ assertFalse(classWriter.hasFlags(ClassWriter.COMPUTE_MAXS));
+ assertFalse(classWriter.hasFlags(ClassWriter.COMPUTE_FRAMES));
+ assertTrue(
+ new ClassFile(classWriter.toByteArray())
+ .toString()
+ .contains(classParameter.getInternalName()));
+ }
+
+ /**
+ * Tests that a ClassReader -> ClassWriter transform with the copy pool option leaves classes
+ * unchanged.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_copyPool(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(classReader, 0);
+
+ classReader.accept(classWriter, attributes(), 0);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> ClassWriter transform with the EXPAND_FRAMES option leaves classes
+ * unchanged.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_expandFrames(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+
+ classReader.accept(classWriter, attributes(), ClassReader.EXPAND_FRAMES);
+
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that a ClassReader -> ClassWriter transform with the COMPUTE_MAXS option leaves classes
+ * unchanged. This is not true in general (the valid max stack and max locals for a given method
+ * are not unique), but this should be the case with our precompiled classes (except
+ * jdk3.SubOptimalMaxStackAndLocals, which has non optimal max values on purpose).
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_computeMaxs(final PrecompiledClass classParameter, final Api apiParameter) {
+ assumeTrue(classParameter != PrecompiledClass.JDK3_SUB_OPTIMAL_MAX_STACK_AND_LOCALS);
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+ classReader.accept(classWriter, attributes(), 0);
+
+ assertTrue(classWriter.hasFlags(ClassWriter.COMPUTE_MAXS));
+ assertFalse(classWriter.hasFlags(ClassWriter.COMPUTE_FRAMES));
+ assertEquals(new ClassFile(classFile), new ClassFile(classWriter.toByteArray()));
+ }
+
+ /**
+ * Tests that classes going through a ClassReader -> ClassWriter transform with the COMPUTE_MAXS
+ * option can be loaded and pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_computeMaxs_newInstance(
+ final PrecompiledClass classParameter, final Api apiParameter) throws Exception {
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ classReader.accept(classWriter, attributes(), 0);
+
+ Executable newInstance = () -> new ClassFile(classWriter.toByteArray()).newInstance();
+
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+
+ /**
+ * Tests that classes going through a ClassReader -> ClassWriter transform with the COMPUTE_FRAMES
+ * option can be loaded and pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_computeFrames(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ assumeFalse(hasJsrOrRetInstructions(classParameter));
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classReader.accept(classWriter, attributes(), 0);
+
+ byte[] newClassFile = classWriter.toByteArray();
+
+ assertFalse(classWriter.hasFlags(ClassWriter.COMPUTE_MAXS));
+ assertTrue(classWriter.hasFlags(ClassWriter.COMPUTE_FRAMES));
+ // The computed stack map frames should be equal to the original ones, if any (classes before
+ // JDK8 don't have ones). This is not true in general (the valid frames for a given method are
+ // not unique), but this should be the case with our precompiled classes (except
+ // jdk3.SubOptimalMaxStackAndLocals, which has non optimal max values on purpose).
+ if (classParameter.isMoreRecentThan(Api.ASM4)
+ && classParameter != PrecompiledClass.JDK3_SUB_OPTIMAL_MAX_STACK_AND_LOCALS) {
+ assertEquals(new ClassFile(classFile), new ClassFile(newClassFile));
+ }
+ Executable newInstance = () -> new ClassFile(newClassFile).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+
+ /**
+ * Tests that classes going through a ClassReader -> ClassWriter transform with the COMPUTE_FRAMES
+ * option can be loaded and pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_computeFrames_jsrInstructions(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ assumeTrue(hasJsrOrRetInstructions(classParameter));
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+
+ Executable accept = () -> classReader.accept(classWriter, attributes(), 0);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, accept);
+ assertEquals("JSR/RET are not supported with computeFrames option", exception.getMessage());
+ }
+
+ /**
+ * Tests that classes going through a ClassReader -> ClassWriter transform with the SKIP_FRAMES
+ * and COMPUTE_FRAMES options can be loaded and pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_skipAndComputeFrames(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ assumeFalse(hasJsrOrRetInstructions(classParameter));
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classReader.accept(classWriter, attributes(), ClassReader.SKIP_FRAMES);
+
+ byte[] newClassFile = classWriter.toByteArray();
+
+ // The computed stack map frames should be equal to the original ones, if any (classes before
+ // JDK8 don't have ones). This is not true in general (the valid frames for a given method are
+ // not unique), but this should be the case with our precompiled classes (except
+ // jdk3.SubOptimalMaxStackAndLocals, which has non optimal max values on purpose).
+ if (classParameter.isMoreRecentThan(Api.ASM4)
+ && classParameter != PrecompiledClass.JDK3_SUB_OPTIMAL_MAX_STACK_AND_LOCALS) {
+ assertEquals(new ClassFile(classFile), new ClassFile(newClassFile));
+ }
+ Executable newInstance = () -> new ClassFile(newClassFile).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+
+ /**
+ * Tests that classes with dead code going through a ClassWriter with the COMPUTE_FRAMES option
+ * can be loaded and pass bytecode verification.
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_computeFramesAndDeadCode(
+ final PrecompiledClass classParameter, final Api apiParameter) {
+ assumeFalse(
+ hasJsrOrRetInstructions(classParameter) || classParameter.isMoreRecentThan(apiParameter));
+ byte[] classFile = classParameter.getBytes();
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ ClassVisitor classVisitor = new DeadCodeInserter(apiParameter.value(), classWriter);
+ classReader.accept(classVisitor, attributes(), ClassReader.SKIP_FRAMES);
+
+ byte[] newClassFile = classWriter.toByteArray();
+
+ Executable newInstance = () -> new ClassFile(newClassFile).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ }
+
+ /**
+ * Tests that classes with large methods (more than 32k) going through a ClassWriter with no
+ * option can be loaded and pass bytecode verification. Also tests that frames are not recomputed
+ * from stratch during this process (by making sure that {@link ClassWriter#getCommonSuperClass}
+ * is not called).
+ */
+ @ParameterizedTest
+ @MethodSource(ALL_CLASSES_AND_ALL_APIS)
+ void testReadAndWrite_largeMethod(final PrecompiledClass classParameter, final Api apiParameter) {
+ byte[] classFile = classParameter.getBytes();
+ assumeFalse(
+ classFile.length > Short.MAX_VALUE || classParameter.isMoreRecentThan(apiParameter));
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriterWithoutGetCommonSuperClass();
+ ForwardJumpNopInserter forwardJumpNopInserter =
+ new ForwardJumpNopInserter(apiParameter.value(), classWriter);
+ classReader.accept(forwardJumpNopInserter, attributes(), 0);
+ if (!forwardJumpNopInserter.transformed) {
+ classWriter = new ClassWriterWithoutGetCommonSuperClass();
+ classReader.accept(
+ new WideForwardJumpInserter(apiParameter.value(), classWriter), attributes(), 0);
+ }
+
+ byte[] transformedClass = classWriter.toByteArray();
+
+ Executable newInstance = () -> new ClassFile(transformedClass).newInstance();
+ if (classParameter.isNotCompatibleWithCurrentJdk()) {
+ assertThrows(UnsupportedClassVersionError.class, newInstance);
+ } else {
+ assertDoesNotThrow(newInstance);
+ }
+ // The transformed class should have the same structure as the original one (#317792).
+ ClassWriter originalClassWithoutCode = new ClassWriter(0);
+ classReader.accept(originalClassWithoutCode, ClassReader.SKIP_CODE);
+ ClassWriter transformedClassWithoutCode = new ClassWriter(0);
+ new ClassReader(transformedClass).accept(transformedClassWithoutCode, ClassReader.SKIP_CODE);
+ assertEquals(
+ new ClassFile(originalClassWithoutCode.toByteArray()),
+ new ClassFile(transformedClassWithoutCode.toByteArray()));
+ }
+
+ private static boolean hasJsrOrRetInstructions(final PrecompiledClass classParameter) {
+ return classParameter == PrecompiledClass.JDK3_ALL_INSTRUCTIONS
+ || classParameter == PrecompiledClass.JDK3_LARGE_METHOD;
+ }
+
+ private static ClassWriter newEmptyClassWriter() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
+ return classWriter;
+ }
+
+ private static String getConstantPoolDump(final ClassWriter classWriter) {
+ return new ClassFile(classWriter.toByteArray()).getConstantPoolDump();
+ }
+
+ private static String getDump(final ClassWriter classWriter) {
+ return new ClassFile(classWriter.toByteArray()).toString();
+ }
+
+ private static Attribute[] attributes() {
+ return new Attribute[] {new Comment(), new CodeComment()};
+ }
+
+ private static class DeadCodeInserter extends ClassVisitor {
+
+ private String className;
+
+ DeadCodeInserter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ className = name;
+ // Set V1_7 version to prevent fallback to old verifier.
+ super.visit(
+ (version & 0xFFFF) < Opcodes.V1_7 ? Opcodes.V1_7 : version,
+ access,
+ name,
+ signature,
+ superName,
+ interfaces);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ int seed = (className + "." + name + descriptor).hashCode();
+ return new MethodDeadCodeInserter(
+ api, seed, super.visitMethod(access, name, descriptor, signature, exceptions));
+ }
+ }
+
+ private static class MethodDeadCodeInserter extends MethodVisitor implements Opcodes {
+
+ private Random random;
+ private boolean inserted;
+
+ MethodDeadCodeInserter(final int api, final int seed, final MethodVisitor methodVisitor) {
+ super(api, methodVisitor);
+ random = new Random(seed);
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ super.visitInsn(opcode);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ super.visitIntInsn(opcode, operand);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ super.visitVarInsn(opcode, varIndex);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ super.visitTypeInsn(opcode, type);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ super.visitInvokeDynamicInsn(
+ name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ super.visitJumpInsn(opcode, label);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (value instanceof Boolean
+ || value instanceof Byte
+ || value instanceof Short
+ || value instanceof Character
+ || value instanceof Integer
+ || value instanceof Long
+ || value instanceof Double
+ || value instanceof Float
+ || value instanceof String
+ || value instanceof Type
+ || value instanceof Handle
+ || value instanceof ConstantDynamic) {
+ super.visitLdcInsn(value);
+ maybeInsertDeadCode();
+ } else {
+ // If this happens, add support for the new type in
+ // MethodWriter.visitLdcInsn(), if needed.
+ throw new IllegalArgumentException("Unsupported type of value: " + value);
+ }
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ super.visitIincInsn(varIndex, increment);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ super.visitTableSwitchInsn(min, max, dflt, labels);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+ super.visitLookupSwitchInsn(dflt, keys, labels);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ maybeInsertDeadCode();
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ if (!inserted) {
+ insertDeadCode();
+ }
+ super.visitMaxs(maxStack, maxLocals);
+ }
+
+ private void maybeInsertDeadCode() {
+ // Inserts dead code once every 50 instructions in average.
+ if (!inserted && random.nextFloat() < 1.0 / 50.0) {
+ insertDeadCode();
+ }
+ }
+
+ private void insertDeadCode() {
+ Label end = new Label();
+ visitJumpInsn(Opcodes.GOTO, end);
+ visitLdcInsn("DEAD CODE");
+ visitLabel(end);
+ inserted = true;
+ }
+ }
+
+ /** Inserts NOP instructions after the first forward jump found, to get a wide jump. */
+ private static class ForwardJumpNopInserter extends ClassVisitor {
+
+ boolean transformed;
+
+ ForwardJumpNopInserter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+ private final HashSet<Label> labels = new HashSet<>();
+
+ @Override
+ public void visitLabel(final Label label) {
+ super.visitLabel(label);
+ labels.add(label);
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ if (!transformed && labels.contains(label)) {
+ transformed = true;
+ for (int i = 0; i <= Short.MAX_VALUE; ++i) {
+ visitInsn(Opcodes.NOP);
+ }
+ }
+ super.visitJumpInsn(opcode, label);
+ }
+ };
+ }
+ }
+
+ /** Inserts a wide forward jump in the first non-abstract method that is found. */
+ private static class WideForwardJumpInserter extends ClassVisitor {
+
+ private boolean needFrames;
+ private boolean transformed;
+
+ WideForwardJumpInserter(final int api, final ClassVisitor classVisitor) {
+ super(api, classVisitor);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ needFrames = (version & 0xFFFF) >= Opcodes.V1_7;
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+ @Override
+ public void visitCode() {
+ super.visitCode();
+ if (!transformed) {
+ Label startLabel = new Label();
+ visitJumpInsn(Opcodes.GOTO, startLabel);
+ if (needFrames) {
+ visitLabel(new Label());
+ visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
+ for (int i = 0; i <= Short.MAX_VALUE; ++i) {
+ visitInsn(Opcodes.NOP);
+ }
+ visitLabel(startLabel);
+ if (needFrames) {
+ visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ visitInsn(Opcodes.NOP);
+ }
+ transformed = true;
+ }
+ }
+ };
+ }
+ }
+
+ /**
+ * A ClassWriter whose {@link ClassWriter#getCommonSuperClass} method always throws an exception.
+ */
+ private static class ClassWriterWithoutGetCommonSuperClass extends ClassWriter {
+
+ public ClassWriterWithoutGetCommonSuperClass() {
+ super(0);
+ }
+
+ @Override
+ protected String getCommonSuperClass(final String type1, final String type2) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/CodeComment.java b/asm/src/test/java/org/objectweb/asm/CodeComment.java
new file mode 100644
index 00000000..71c4d6fe
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/CodeComment.java
@@ -0,0 +1,71 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A non standard code attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class CodeComment extends Attribute {
+
+ public CodeComment() {
+ super("CodeComment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new CodeComment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/Comment.java b/asm/src/test/java/org/objectweb/asm/Comment.java
new file mode 100644
index 00000000..748abd00
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/Comment.java
@@ -0,0 +1,66 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+/**
+ * A non standard attribute used for testing purposes.
+ *
+ * @author Eric Bruneton
+ */
+public class Comment extends Attribute {
+
+ public Comment() {
+ super("Comment");
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return false;
+ }
+
+ @Override
+ protected Attribute read(
+ final ClassReader classReader,
+ final int offset,
+ final int length,
+ final char[] charBuffer,
+ final int codeAttributeOffset,
+ final Label[] labels) {
+ return new Comment();
+ }
+
+ @Override
+ protected ByteVector write(
+ final ClassWriter classWriter,
+ final byte[] code,
+ final int codeLength,
+ final int maxStack,
+ final int maxLocals) {
+ return new ByteVector();
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ConstantsTest.java b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java
new file mode 100644
index 00000000..f2ca92a2
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java
@@ -0,0 +1,569 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link Constants}.
+ *
+ * @author Eric Bruneton
+ */
+class ConstantsTest {
+
+ private enum ConstantType {
+ ASM_VERSION,
+ CLASS_VERSION,
+ ACCESS_FLAG,
+ ASM_ACCESS_FLAG,
+ NEW_ARRAY_TYPE,
+ REFERENCE_KIND,
+ FRAME_TYPE,
+ VERIFICATION_TYPE_INFO_TAG,
+ OPCODE,
+ OTHER
+ };
+
+ @Test
+ void testAsmVersions() {
+ List<Field> asmVersions = getConstants(ConstantType.ASM_VERSION);
+
+ Set<Integer> asmVersionValues =
+ asmVersions.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(asmVersions.size(), asmVersionValues.size());
+ }
+
+ @Test
+ void testClassVersions() {
+ List<Field> classVersions = getConstants(ConstantType.CLASS_VERSION);
+
+ Set<Integer> classVersionValues =
+ classVersions.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(classVersions.size(), classVersionValues.size());
+ }
+
+ @Test
+ void testAccessFlags() throws IllegalAccessException {
+ List<Field> accessFlags = getConstants(ConstantType.ACCESS_FLAG);
+
+ for (Field accessFlag : accessFlags) {
+ assertEquals(0, accessFlag.getInt(null) & ~0xFFFF);
+ assertEquals(1, Integer.bitCount(accessFlag.getInt(null)));
+ }
+ }
+
+ @Test
+ void testAsmAccessFlags() throws IllegalAccessException {
+ List<Field> asmAccessFlags = getConstants(ConstantType.ASM_ACCESS_FLAG);
+
+ for (Field asmAccessFlag : asmAccessFlags) {
+ assertEquals(0, asmAccessFlag.getInt(null) & 0xFFFF);
+ assertEquals(1, Integer.bitCount(asmAccessFlag.getInt(null)));
+ }
+ }
+
+ @Test
+ void testNewArrayTypes() {
+ List<Field> newArrayTypes = getConstants(ConstantType.NEW_ARRAY_TYPE);
+
+ Set<Integer> newArrayTypeValues =
+ newArrayTypes.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(newArrayTypes.size(), newArrayTypeValues.size());
+ for (int newArrayType : newArrayTypeValues) {
+ assertEquals(0, newArrayType & ~0xFF);
+ }
+ }
+
+ @Test
+ void testReferenceKinds() {
+ List<Field> referenceKinds = getConstants(ConstantType.REFERENCE_KIND);
+
+ Set<Integer> referenceKindValues =
+ referenceKinds.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(referenceKinds.size(), referenceKindValues.size());
+ for (int referenceKind : referenceKindValues) {
+ assertEquals(0, referenceKind & ~0xFF);
+ }
+ }
+
+ @Test
+ void testFrameTypes() {
+ List<Field> frameTypes = getConstants(ConstantType.FRAME_TYPE);
+
+ Set<Integer> frameTypeValues =
+ frameTypes.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(frameTypes.size(), frameTypeValues.size());
+ }
+
+ @Test
+ void testVerificationTypeInfoTags() {
+ List<Field> verificationTypeInfoTags = getConstants(ConstantType.VERIFICATION_TYPE_INFO_TAG);
+
+ Set<Integer> verificationTypeInfoTagValues =
+ verificationTypeInfoTags.stream()
+ .map(ConstantsTest::getIntegerValue)
+ .collect(Collectors.toSet());
+
+ assertEquals(verificationTypeInfoTags.size(), verificationTypeInfoTagValues.size());
+ for (int verificationTypeInfoTag : verificationTypeInfoTagValues) {
+ assertEquals(0, verificationTypeInfoTag & ~0xFF);
+ }
+ }
+
+ @Test
+ void testOpcodes() {
+ List<Field> opcodes = getConstants(ConstantType.OPCODE);
+
+ Set<Integer> opcodeValues =
+ opcodes.stream().map(ConstantsTest::getIntValue).collect(Collectors.toSet());
+
+ assertEquals(opcodes.size(), opcodeValues.size());
+ for (int opcode : opcodeValues) {
+ assertEquals(0, opcode & ~0xFF);
+ assertEquals(0, opcode & Opcodes.SOURCE_MASK);
+ }
+ }
+
+ @Test
+ void testIsWhitelisted() {
+ assertFalse(Constants.isWhitelisted("org/jacoco/core/internal/flow/ClassProbesVisitor"));
+ assertFalse(Constants.isWhitelisted("org/objectweb/asm/ClassWriter"));
+ assertFalse(Constants.isWhitelisted("org/objectweb/asm/util/CheckClassVisitor"));
+ assertFalse(Constants.isWhitelisted("org/objectweb/asm/ClassWriterTest"));
+ assertTrue(Constants.isWhitelisted("org/objectweb/asm/ClassWriterTest$DeadCodeInserter"));
+ assertTrue(Constants.isWhitelisted("org/objectweb/asm/util/TraceClassVisitor"));
+ assertTrue(Constants.isWhitelisted("org/objectweb/asm/util/CheckClassAdapter"));
+ }
+
+ @Test
+ void testCheckIsPreview_nullStream() {
+ Executable checkIsPreview = () -> Constants.checkIsPreview(null);
+
+ assertThrows(IllegalStateException.class, checkIsPreview);
+ }
+
+ @Test
+ void testCheckIsPreview_invalidStream() {
+ InputStream invalidStream = new ByteArrayInputStream(new byte[4]);
+
+ Executable checkIsPreview = () -> Constants.checkIsPreview(invalidStream);
+
+ assertThrows(IllegalStateException.class, checkIsPreview);
+ }
+
+ @Test
+ void testCheckIsPreview_nonPreviewClass() {
+ InputStream nonPreviewStream = new ByteArrayInputStream(new byte[8]);
+
+ Executable checkIsPreview = () -> Constants.checkIsPreview(nonPreviewStream);
+
+ assertThrows(IllegalStateException.class, checkIsPreview);
+ }
+
+ @Test
+ void testCheckIsPreview_previewClass() {
+ byte[] previewClass = new byte[] {0, 0, 0, 0, (byte) 0xFF, (byte) 0xFF};
+ InputStream previewStream = new ByteArrayInputStream(previewClass);
+
+ Executable checkIsPreview = () -> Constants.checkIsPreview(previewStream);
+
+ assertDoesNotThrow(checkIsPreview);
+ }
+
+ private static List<Field> getConstants(final ConstantType constantType) {
+ return Stream.concat(
+ Arrays.stream(Opcodes.class.getFields()), Arrays.stream(Constants.class.getFields()))
+ .filter(field -> getType(field).equals(constantType))
+ .collect(Collectors.toList());
+ }
+
+ private static ConstantType getType(final Field field) {
+ switch (field.getName()) {
+ case "ASM4":
+ case "ASM5":
+ case "ASM6":
+ case "ASM7":
+ case "ASM8":
+ case "ASM9":
+ case "ASM10_EXPERIMENTAL":
+ return ConstantType.ASM_VERSION;
+ case "V_PREVIEW":
+ case "V1_1":
+ case "V1_2":
+ case "V1_3":
+ case "V1_4":
+ case "V1_5":
+ case "V1_6":
+ case "V1_7":
+ case "V1_8":
+ case "V9":
+ case "V10":
+ case "V11":
+ case "V12":
+ case "V13":
+ case "V14":
+ case "V15":
+ case "V16":
+ case "V17":
+ case "V18":
+ case "V19":
+ case "V20":
+ return ConstantType.CLASS_VERSION;
+ case "ACC_PUBLIC":
+ case "ACC_PRIVATE":
+ case "ACC_PROTECTED":
+ case "ACC_STATIC":
+ case "ACC_FINAL":
+ case "ACC_SUPER":
+ case "ACC_SYNCHRONIZED":
+ case "ACC_OPEN":
+ case "ACC_TRANSITIVE":
+ case "ACC_VOLATILE":
+ case "ACC_BRIDGE":
+ case "ACC_STATIC_PHASE":
+ case "ACC_VARARGS":
+ case "ACC_TRANSIENT":
+ case "ACC_NATIVE":
+ case "ACC_INTERFACE":
+ case "ACC_ABSTRACT":
+ case "ACC_STRICT":
+ case "ACC_SYNTHETIC":
+ case "ACC_ANNOTATION":
+ case "ACC_ENUM":
+ case "ACC_MANDATED":
+ case "ACC_MODULE":
+ case "ACC_SEALED":
+ return ConstantType.ACCESS_FLAG;
+ case "ACC_RECORD":
+ case "ACC_DEPRECATED":
+ case "ACC_CONSTRUCTOR":
+ return ConstantType.ASM_ACCESS_FLAG;
+ case "T_BOOLEAN":
+ case "T_CHAR":
+ case "T_FLOAT":
+ case "T_DOUBLE":
+ case "T_BYTE":
+ case "T_SHORT":
+ case "T_INT":
+ case "T_LONG":
+ return ConstantType.NEW_ARRAY_TYPE;
+ case "H_GETFIELD":
+ case "H_GETSTATIC":
+ case "H_PUTFIELD":
+ case "H_PUTSTATIC":
+ case "H_INVOKEVIRTUAL":
+ case "H_INVOKESTATIC":
+ case "H_INVOKESPECIAL":
+ case "H_NEWINVOKESPECIAL":
+ case "H_INVOKEINTERFACE":
+ return ConstantType.REFERENCE_KIND;
+ case "F_NEW":
+ case "F_FULL":
+ case "F_APPEND":
+ case "F_CHOP":
+ case "F_SAME":
+ case "F_SAME1":
+ case "F_INSERT":
+ return ConstantType.FRAME_TYPE;
+ case "TOP":
+ case "INTEGER":
+ case "FLOAT":
+ case "DOUBLE":
+ case "LONG":
+ case "NULL":
+ case "UNINITIALIZED_THIS":
+ return ConstantType.VERIFICATION_TYPE_INFO_TAG;
+ case "NOP":
+ case "ACONST_NULL":
+ case "ICONST_M1":
+ case "ICONST_0":
+ case "ICONST_1":
+ case "ICONST_2":
+ case "ICONST_3":
+ case "ICONST_4":
+ case "ICONST_5":
+ case "LCONST_0":
+ case "LCONST_1":
+ case "FCONST_0":
+ case "FCONST_1":
+ case "FCONST_2":
+ case "DCONST_0":
+ case "DCONST_1":
+ case "BIPUSH":
+ case "SIPUSH":
+ case "LDC":
+ case "LDC_W":
+ case "LDC2_W":
+ case "ILOAD":
+ case "LLOAD":
+ case "FLOAD":
+ case "DLOAD":
+ case "ALOAD":
+ case "ILOAD_0":
+ case "ILOAD_1":
+ case "ILOAD_2":
+ case "ILOAD_3":
+ case "LLOAD_0":
+ case "LLOAD_1":
+ case "LLOAD_2":
+ case "LLOAD_3":
+ case "FLOAD_0":
+ case "FLOAD_1":
+ case "FLOAD_2":
+ case "FLOAD_3":
+ case "DLOAD_0":
+ case "DLOAD_1":
+ case "DLOAD_2":
+ case "DLOAD_3":
+ case "ALOAD_0":
+ case "ALOAD_1":
+ case "ALOAD_2":
+ case "ALOAD_3":
+ case "IALOAD":
+ case "LALOAD":
+ case "FALOAD":
+ case "DALOAD":
+ case "AALOAD":
+ case "BALOAD":
+ case "CALOAD":
+ case "SALOAD":
+ case "ISTORE":
+ case "LSTORE":
+ case "FSTORE":
+ case "DSTORE":
+ case "ASTORE":
+ case "ISTORE_0":
+ case "ISTORE_1":
+ case "ISTORE_2":
+ case "ISTORE_3":
+ case "LSTORE_0":
+ case "LSTORE_1":
+ case "LSTORE_2":
+ case "LSTORE_3":
+ case "FSTORE_0":
+ case "FSTORE_1":
+ case "FSTORE_2":
+ case "FSTORE_3":
+ case "DSTORE_0":
+ case "DSTORE_1":
+ case "DSTORE_2":
+ case "DSTORE_3":
+ case "ASTORE_0":
+ case "ASTORE_1":
+ case "ASTORE_2":
+ case "ASTORE_3":
+ case "IASTORE":
+ case "LASTORE":
+ case "FASTORE":
+ case "DASTORE":
+ case "AASTORE":
+ case "BASTORE":
+ case "CASTORE":
+ case "SASTORE":
+ case "POP":
+ case "POP2":
+ case "DUP":
+ case "DUP_X1":
+ case "DUP_X2":
+ case "DUP2":
+ case "DUP2_X1":
+ case "DUP2_X2":
+ case "SWAP":
+ case "IADD":
+ case "LADD":
+ case "FADD":
+ case "DADD":
+ case "ISUB":
+ case "LSUB":
+ case "FSUB":
+ case "DSUB":
+ case "IMUL":
+ case "LMUL":
+ case "FMUL":
+ case "DMUL":
+ case "IDIV":
+ case "LDIV":
+ case "FDIV":
+ case "DDIV":
+ case "IREM":
+ case "LREM":
+ case "FREM":
+ case "DREM":
+ case "INEG":
+ case "LNEG":
+ case "FNEG":
+ case "DNEG":
+ case "ISHL":
+ case "LSHL":
+ case "ISHR":
+ case "LSHR":
+ case "IUSHR":
+ case "LUSHR":
+ case "IAND":
+ case "LAND":
+ case "IOR":
+ case "LOR":
+ case "IXOR":
+ case "LXOR":
+ case "IINC":
+ case "I2L":
+ case "I2F":
+ case "I2D":
+ case "L2I":
+ case "L2F":
+ case "L2D":
+ case "F2I":
+ case "F2L":
+ case "F2D":
+ case "D2I":
+ case "D2L":
+ case "D2F":
+ case "I2B":
+ case "I2C":
+ case "I2S":
+ case "LCMP":
+ case "FCMPL":
+ case "FCMPG":
+ case "DCMPL":
+ case "DCMPG":
+ case "IFEQ":
+ case "IFNE":
+ case "IFLT":
+ case "IFGE":
+ case "IFGT":
+ case "IFLE":
+ case "IF_ICMPEQ":
+ case "IF_ICMPNE":
+ case "IF_ICMPLT":
+ case "IF_ICMPGE":
+ case "IF_ICMPGT":
+ case "IF_ICMPLE":
+ case "IF_ACMPEQ":
+ case "IF_ACMPNE":
+ case "GOTO":
+ case "JSR":
+ case "RET":
+ case "TABLESWITCH":
+ case "LOOKUPSWITCH":
+ case "IRETURN":
+ case "LRETURN":
+ case "FRETURN":
+ case "DRETURN":
+ case "ARETURN":
+ case "RETURN":
+ case "GETSTATIC":
+ case "PUTSTATIC":
+ case "GETFIELD":
+ case "PUTFIELD":
+ case "INVOKEVIRTUAL":
+ case "INVOKESPECIAL":
+ case "INVOKESTATIC":
+ case "INVOKEINTERFACE":
+ case "INVOKEDYNAMIC":
+ case "NEW":
+ case "NEWARRAY":
+ case "ANEWARRAY":
+ case "ARRAYLENGTH":
+ case "ATHROW":
+ case "CHECKCAST":
+ case "INSTANCEOF":
+ case "MONITORENTER":
+ case "MONITOREXIT":
+ case "WIDE":
+ case "MULTIANEWARRAY":
+ case "IFNULL":
+ case "IFNONNULL":
+ case "GOTO_W":
+ case "JSR_W":
+ case "ASM_IFEQ":
+ case "ASM_IFNE":
+ case "ASM_IFLT":
+ case "ASM_IFGE":
+ case "ASM_IFGT":
+ case "ASM_IFLE":
+ case "ASM_IF_ICMPEQ":
+ case "ASM_IF_ICMPNE":
+ case "ASM_IF_ICMPLT":
+ case "ASM_IF_ICMPGE":
+ case "ASM_IF_ICMPGT":
+ case "ASM_IF_ICMPLE":
+ case "ASM_IF_ACMPEQ":
+ case "ASM_IF_ACMPNE":
+ case "ASM_GOTO":
+ case "ASM_JSR":
+ case "ASM_IFNULL":
+ case "ASM_IFNONNULL":
+ case "ASM_GOTO_W":
+ return ConstantType.OPCODE;
+ case "WIDE_JUMP_OPCODE_DELTA":
+ case "ASM_OPCODE_DELTA":
+ case "ASM_IFNULL_OPCODE_DELTA":
+ case "SOURCE_DEPRECATED":
+ case "SOURCE_MASK":
+ return ConstantType.OTHER;
+ default:
+ throw new IllegalArgumentException("Unknown constant " + field.getName());
+ }
+ }
+
+ private static int getIntValue(final Field field) {
+ try {
+ return field.getInt(null);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private static int getIntegerValue(final Field field) {
+ try {
+ return ((Integer) field.get(null)).intValue();
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/FieldVisitorTest.java b/asm/src/test/java/org/objectweb/asm/FieldVisitorTest.java
new file mode 100644
index 00000000..b7f37cd7
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/FieldVisitorTest.java
@@ -0,0 +1,67 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link FieldVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class FieldVisitorTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new FieldVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new FieldVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ FieldVisitor delegate = new FieldVisitor(Opcodes.ASM4) {};
+ FieldVisitor visitor = new FieldVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/HandleTest.java b/asm/src/test/java/org/objectweb/asm/HandleTest.java
new file mode 100644
index 00000000..be8d8c88
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/HandleTest.java
@@ -0,0 +1,106 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link Handle}.
+ *
+ * @author Eric Bruneton
+ */
+class HandleTest {
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedConstructor() {
+ Handle handle1 = new Handle(Opcodes.H_INVOKEINTERFACE, "owner", "name", "descriptor");
+ Handle handle2 = new Handle(Opcodes.H_INVOKESPECIAL, "owner", "name", "descriptor");
+
+ assertTrue(handle1.isInterface());
+ assertFalse(handle2.isInterface());
+ assertEquals("owner.namedescriptor (9 itf)", handle1.toString());
+ assertEquals("owner.namedescriptor (7)", handle2.toString());
+ }
+
+ @Test
+ void testConstructor() {
+ Handle handle = new Handle(Opcodes.H_GETFIELD, "owner", "name", "descriptor", false);
+
+ assertEquals(Opcodes.H_GETFIELD, handle.getTag());
+ assertEquals("owner", handle.getOwner());
+ assertEquals("name", handle.getName());
+ assertEquals("descriptor", handle.getDesc());
+ assertFalse(handle.isInterface());
+ assertEquals("owner.namedescriptor (1)", handle.toString());
+ }
+
+ @Test
+ void testEquals() {
+ Handle handle1 = new Handle(Opcodes.H_GETFIELD, "owner", "name", "descriptor", false);
+ Handle handle2 = new Handle(Opcodes.H_GETFIELD, "owner", "name", "descriptor", false);
+ Handle nullHandle = null;
+
+ final boolean equalsThis = handle1.equals(handle1);
+ final boolean equalsSame = handle1.equals(handle2);
+ final boolean equalsNull = handle1.equals(nullHandle);
+ final boolean equalsHandleWithDifferentTag =
+ handle1.equals(new Handle(Opcodes.H_PUTFIELD, "owner", "name", "descriptor", false));
+ final boolean equalsHandleWithDifferentOwner =
+ handle1.equals(new Handle(Opcodes.H_GETFIELD, "o", "name", "descriptor", false));
+ final boolean equalsHandleWithDifferentName =
+ handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", false));
+ final boolean equalsHandleWithDifferentDescriptor =
+ handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "name", "d", false));
+ final boolean equalsHandleWithDifferentIsInterface =
+ handle1.equals(new Handle(Opcodes.H_GETFIELD, "owner", "n", "descriptor", true));
+
+ assertTrue(equalsThis);
+ assertTrue(equalsSame);
+ assertFalse(equalsNull);
+ assertFalse(equalsHandleWithDifferentTag);
+ assertFalse(equalsHandleWithDifferentOwner);
+ assertFalse(equalsHandleWithDifferentName);
+ assertFalse(equalsHandleWithDifferentDescriptor);
+ assertFalse(equalsHandleWithDifferentIsInterface);
+ }
+
+ @Test
+ void testHashCode() {
+ Handle handle1 = new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", false);
+ Handle handle2 = new Handle(Opcodes.H_INVOKESTATIC, "owner", "name", "descriptor", true);
+
+ assertNotEquals(0, handle1.hashCode());
+ assertNotEquals(0, handle2.hashCode());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/HandlerTest.java b/asm/src/test/java/org/objectweb/asm/HandlerTest.java
new file mode 100644
index 00000000..8143f8cd
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/HandlerTest.java
@@ -0,0 +1,153 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link Handler}.
+ *
+ * @author Eric Bruneton
+ */
+class HandlerTest {
+
+ @Test
+ void testConstructor() {
+ Label startPc = new Label();
+ Label endPc = new Label();
+ Label handlerPc = new Label();
+ int catchType = 123;
+ String catchDescriptor = "123";
+
+ Handler handler = new Handler(startPc, endPc, handlerPc, catchType, catchDescriptor);
+
+ assertEquals(startPc, handler.startPc);
+ assertEquals(endPc, handler.endPc);
+ assertEquals(handlerPc, handler.handlerPc);
+ assertEquals(catchType, handler.catchType);
+ assertEquals(catchDescriptor, handler.catchTypeDescriptor);
+ }
+
+ @Test
+ void testCopyConstructor() {
+ Label startPc1 = new Label();
+ Label endPc1 = new Label();
+ Label handlerPc = new Label();
+ int catchType = 123;
+ String catchDescriptor = "123";
+ Handler handler1 = new Handler(startPc1, endPc1, handlerPc, catchType, catchDescriptor);
+ Label startPc2 = new Label();
+ Label endPc2 = new Label();
+
+ Handler handler2 = new Handler(handler1, startPc2, endPc2);
+
+ assertEquals(startPc2, handler2.startPc);
+ assertEquals(endPc2, handler2.endPc);
+ assertEquals(handlerPc, handler2.handlerPc);
+ assertEquals(catchType, handler2.catchType);
+ assertEquals(catchDescriptor, handler2.catchTypeDescriptor);
+ }
+
+ @Test
+ void testRemoveRange_removeAllOrNothing() {
+ Handler handler = newHandler(10, 20);
+
+ assertEquals(null, Handler.removeRange(null, newLabel(0), newLabel(10)));
+ assertEquals(handler, Handler.removeRange(handler, newLabel(0), newLabel(10)));
+ assertEquals(handler, Handler.removeRange(handler, newLabel(20), newLabel(30)));
+ assertEquals(handler, Handler.removeRange(handler, newLabel(20), null));
+ assertEquals(null, Handler.removeRange(handler, newLabel(0), newLabel(30)));
+ }
+
+ @Test
+ void testRemoveRange_removeStart() {
+ Handler handler = Handler.removeRange(newHandler(10, 20), newLabel(0), newLabel(15));
+
+ assertEquals(15, handler.startPc.bytecodeOffset);
+ assertEquals(20, handler.endPc.bytecodeOffset);
+ assertEquals(null, handler.nextHandler);
+ }
+
+ @Test
+ void testRemoveRange_removeEnd() {
+ Handler handler = Handler.removeRange(newHandler(10, 20), newLabel(15), newLabel(30));
+
+ assertEquals(10, handler.startPc.bytecodeOffset);
+ assertEquals(15, handler.endPc.bytecodeOffset);
+ assertEquals(null, handler.nextHandler);
+ }
+
+ @Test
+ void testRemoveRange_removeMiddle() {
+ Handler handler = Handler.removeRange(newHandler(10, 20), newLabel(13), newLabel(17));
+
+ assertEquals(10, handler.startPc.bytecodeOffset);
+ assertEquals(13, handler.endPc.bytecodeOffset);
+ assertEquals(17, handler.nextHandler.startPc.bytecodeOffset);
+ assertEquals(20, handler.nextHandler.endPc.bytecodeOffset);
+ assertEquals(null, handler.nextHandler.nextHandler);
+ }
+
+ @Test
+ void testGetExceptionTableLength() {
+ Handler handler = newHandler(10, 20);
+
+ assertEquals(0, Handler.getExceptionTableLength(null));
+ assertEquals(1, Handler.getExceptionTableLength(handler));
+ }
+
+ @Test
+ void testGetExceptionTableSize() {
+ Handler handlerList = Handler.removeRange(newHandler(10, 20), newLabel(13), newLabel(17));
+
+ assertEquals(2, Handler.getExceptionTableSize(null));
+ assertEquals(18, Handler.getExceptionTableSize(handlerList));
+ }
+
+ @Test
+ void testPutExceptionTable() {
+ Handler handlerList = Handler.removeRange(newHandler(10, 20), newLabel(13), newLabel(17));
+ ByteVector byteVector = new ByteVector();
+
+ Handler.putExceptionTable(handlerList, byteVector);
+
+ assertEquals(18, byteVector.length);
+ }
+
+ private static Handler newHandler(final int startPc, final int endPc) {
+ return new Handler(newLabel(startPc), newLabel(endPc), newLabel(0), 0, "");
+ }
+
+ private static Label newLabel(final int bytecodeOffset) {
+ Label label = new Label();
+ label.bytecodeOffset = bytecodeOffset;
+ return label;
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/LabelTest.java b/asm/src/test/java/org/objectweb/asm/LabelTest.java
new file mode 100644
index 00000000..d182ea53
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/LabelTest.java
@@ -0,0 +1,73 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link Label}.
+ *
+ * @author Eric Bruneton
+ */
+class LabelTest {
+
+ /** Tests that {@link Label#getOffset()} returns a correct offset after the label is visited. */
+ @Test
+ void testGetOffset() {
+ MethodVisitor methodVisitor =
+ new ClassWriter(0).visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ Label label = new Label();
+
+ methodVisitor.visitLabel(label);
+
+ assertEquals(1, label.getOffset());
+ }
+
+ /** Tests that {@link Label#getOffset()} throws an exception before the label is visited. */
+ @Test
+ void testGetOffset_illegalState() {
+ Executable getOffset = () -> new Label().getOffset();
+
+ Exception exception = assertThrows(IllegalStateException.class, getOffset);
+ assertEquals("Label offset position has not been resolved yet", exception.getMessage());
+ }
+
+ /** Tests that {@link Label#toString()} returns strings starting with "L". */
+ @Test
+ void testToString() {
+ String string = new Label().toString();
+
+ assertEquals('L', string.charAt(0));
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java b/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java
new file mode 100644
index 00000000..915b1b4d
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java
@@ -0,0 +1,567 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.StringWriter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * Unit tests for {@link MethodVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class MethodVisitorTest extends AsmTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new MethodVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new MethodVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ MethodVisitor delegate = new MethodVisitor(Opcodes.ASM4) {};
+ MethodVisitor visitor = new MethodVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+
+ @Test
+ void testVisitParameter_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitParameter = () -> methodVisitor.visitParameter(null, 0);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitParameter);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitTypeAnnotation_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitTypeAnnotation = () -> methodVisitor.visitTypeAnnotation(0, null, null, false);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitTypeAnnotation);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitInvokeDynamicInsn_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitInvokeDynamicInsn =
+ () -> methodVisitor.visitInvokeDynamicInsn(null, null, null);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitInvokeDynamicInsn);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitInsnAnnotation_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitInsnAnnotation = () -> methodVisitor.visitInsnAnnotation(0, null, null, false);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitInsnAnnotation);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitTryCatchAnnotation_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitTryCatchAnnotation =
+ () -> methodVisitor.visitTryCatchAnnotation(0, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitTryCatchAnnotation);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitLocalVariableAnnotation_asm4Visitor() {
+ MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4, null) {};
+
+ Executable visitLocalVariableAnnotation =
+ () -> methodVisitor.visitLocalVariableAnnotation(0, null, null, null, null, null, false);
+
+ Exception exception =
+ assertThrows(UnsupportedOperationException.class, visitLocalVariableAnnotation);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ @Test
+ void testVisitFrame_consecutiveFrames_sameFrame() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "C", null, "D", null);
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_STATIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+
+ Executable visitFrame = () -> methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+
+ assertDoesNotThrow(visitFrame);
+ }
+
+ @Test
+ void testVisitFrame_consecutiveFrames() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "C", null, "D", null);
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_STATIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+
+ Executable visitFrame =
+ () ->
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+
+ assertThrows(IllegalStateException.class, visitFrame);
+ }
+
+ @Test
+ void testVisitFrame_compressedFrameWithV1_5class() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "C", null, "D", null);
+ MethodVisitor methodVisitor =
+ new ClassWriter(0).visitMethod(Opcodes.ACC_STATIC, "m", "()V", null, null);
+ methodVisitor.visitCode();
+
+ Executable visitFrame = () -> methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+
+ Exception exception = assertThrows(IllegalArgumentException.class, visitFrame);
+ assertTrue(exception.getMessage().contains("versions V1_5 or less must use F_NEW frames."));
+ }
+
+ /** Tests the ASM4 visitMethodInsn on an ASM4 visitor. */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_asm4Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4(logMethodVisitor);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals("LogMethodVisitor:m()V;", log.toString());
+ }
+
+ /** Tests the ASM4 visitMethodInsn on an ASM4 visitor which overrides this method. */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_overridenAsm4Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4Override(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals("LogMethodVisitor:m4()V;MethodVisitor4:m()V;", log.toString());
+ }
+
+ /** Tests the ASM4 visitMethodInsn on an ASM5 visitor. */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_asm5Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor5(logMethodVisitor);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals("LogMethodVisitor:m()V;", log.toString());
+ }
+
+ /** Tests the ASM4 visitMethodInsn on an ASM5 visitor which overrides the ASM5 method. */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_overridenAsm5Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor5Override(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals("LogMethodVisitor:m5()V;MethodVisitor5:m()V;", log.toString());
+ }
+
+ /**
+ * Tests the ASM4 visitMethodInsn on an ASM4 visitor which overrides this method, and is a
+ * subclass of an ASM subclass of MethodVisitor.
+ */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_userTraceMethodVisitor4() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new UserTraceMethodVisitor4(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals(
+ "LogMethodVisitor:m()V;TraceMethodVisitor:m()V;UserTraceMethodVisitor4:m()V;",
+ log.toString());
+ }
+
+ /**
+ * Tests the ASM4 visitMethodInsn on an ASM5 visitor which overrides the ASM5 method, and is a
+ * subclass of an ASM subclass of MethodVisitor.
+ */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_userTraceMethodVisitor5() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new UserTraceMethodVisitor5(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals(
+ "LogMethodVisitor:m()V;TraceMethodVisitor:m()V;UserTraceMethodVisitor5:m()V;",
+ log.toString());
+ }
+
+ /**
+ * Tests that method visitors with different API versions can be chained together and produce the
+ * expected result, when calling the ASM4 visitMethodInsn on the first visitor.
+ */
+ @Test
+ @SuppressWarnings("deprecation")
+ void testDeprecatedVisitMethodInsn_mixedVisitorChain() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor =
+ new MethodVisitor4Override(
+ new MethodVisitor4(
+ new MethodVisitor5Override(new MethodVisitor5(logMethodVisitor), log)),
+ log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V");
+
+ assertEquals(
+ "LogMethodVisitor:m45()V;MethodVisitor5:m4()V;MethodVisitor4:m()V;", log.toString());
+ }
+
+ /** Tests the ASM5 visitMethodInsn on an ASM4 visitor, with isInterface set to false. */
+ @Test
+ void testVisitMethodInsn_asm4Visitor_isNotInterface() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4(logMethodVisitor);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals("LogMethodVisitor:m()V;", log.toString());
+ }
+
+ /** Tests the ASM5 visitMethodInsn on an ASM4 visitor, with isInterface set to true. */
+ @Test
+ void testVisitMethodInsn_asm4Visitor_isInterface() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4(logMethodVisitor);
+
+ Executable visitMethodInsn = () -> methodVisitor.visitMethodInsn(0, "C", "m", "()V", true);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMethodInsn);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ /**
+ * Tests the ASM5 visitMethodInsn on an ASM4 visitor which overrides the ASM4 method, with
+ * isInterface set to false.
+ */
+ @Test
+ void testVisitMethodInsn_overridenAsm4Visitor_isNotInterface() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4Override(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals("LogMethodVisitor:m4()V;MethodVisitor4:m()V;", log.toString());
+ }
+
+ /**
+ * Tests the ASM5 visitMethodInsn on an ASM4 visitor which overrides the ASM4 method, with
+ * isInterface set to true.
+ */
+ @Test
+ void testVisitMethodInsn_overridenAsm4Visitor_isInterface() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor4Override(logMethodVisitor, log);
+
+ Executable visitMethodInsn = () -> methodVisitor.visitMethodInsn(0, "C", "m", "()V", true);
+
+ Exception exception = assertThrows(UnsupportedOperationException.class, visitMethodInsn);
+ assertTrue(exception.getMessage().matches(UNSUPPORTED_OPERATION_MESSAGE_PATTERN));
+ }
+
+ /** Tests the ASM5 visitMethodInsn on an ASM5 visitor. */
+ @Test
+ void testVisitMethodInsn_asm5Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor5(logMethodVisitor);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals("LogMethodVisitor:m()V;", log.toString());
+ }
+
+ /** Tests the ASM5 visitMethodInsn on an ASM5 visitor which overrides this method. */
+ @Test
+ void testVisitMethodInsn_overridenAsm5Visitor() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new MethodVisitor5Override(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals("LogMethodVisitor:m5()V;MethodVisitor5:m()V;", log.toString());
+ }
+
+ /**
+ * Tests the ASM5 visitMethodInsn on an ASM4 visitor which overrides this method, and is a
+ * subclass of an ASM subclass of MethodVisitor.
+ */
+ @Test
+ void testVisitMethodInsn_userTraceMethodVisitor4() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new UserTraceMethodVisitor4(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals(
+ "LogMethodVisitor:m()V;TraceMethodVisitor:m()V;UserTraceMethodVisitor4:m()V;",
+ log.toString());
+ }
+
+ /**
+ * Tests the ASM5 visitMethodInsn on an ASM5 visitor which overrides this method, and is a
+ * subclass of an ASM subclass of MethodVisitor.
+ */
+ @Test
+ void testVisitMethodInsn_userTraceMethodVisitor5() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor = new UserTraceMethodVisitor5(logMethodVisitor, log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals(
+ "LogMethodVisitor:m()V;TraceMethodVisitor:m()V;UserTraceMethodVisitor5:m()V;",
+ log.toString());
+ }
+
+ /**
+ * Tests that method visitors with different API versions can be chained together and produce the
+ * expected result, when calling the ASM5 visitMethodInsn on the first visitor.
+ */
+ @Test
+ void testVisitMethodInsn_mixedVisitorChain() {
+ StringWriter log = new StringWriter();
+ LogMethodVisitor logMethodVisitor = new LogMethodVisitor(log);
+ MethodVisitor methodVisitor =
+ new MethodVisitor5Override(
+ new MethodVisitor5(
+ new MethodVisitor4Override(new MethodVisitor4(logMethodVisitor), log)),
+ log);
+
+ methodVisitor.visitMethodInsn(0, "C", "m", "()V", false);
+
+ assertEquals(
+ "LogMethodVisitor:m54()V;MethodVisitor4:m5()V;MethodVisitor5:m()V;", log.toString());
+ }
+
+ /** An ASM4 {@link MethodVisitor} which does not override the ASM4 visitMethodInsn method. */
+ private static class MethodVisitor4 extends MethodVisitor {
+ MethodVisitor4(final MethodVisitor methodVisitor) {
+ super(Opcodes.ASM4, methodVisitor);
+ }
+ }
+
+ /**
+ * An ASM4 {@link MethodVisitor} which overrides the ASM4 visitMethodInsn method, by adding "v4"
+ * at the end of method names and by duplicating the instruction.
+ */
+ private static class MethodVisitor4Override extends MethodVisitor {
+
+ private final StringWriter log;
+
+ MethodVisitor4Override(final MethodVisitor methodVisitor, final StringWriter log) {
+ super(Opcodes.ASM4, methodVisitor);
+ this.log = log;
+ }
+
+ @Deprecated
+ @Override
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitMethodInsn(opcode, owner, name + "4", descriptor);
+ log.append("MethodVisitor4:" + name + descriptor + ";");
+ }
+ }
+
+ /** An ASM5 {@link MethodVisitor} which does not override the ASM5 visitMethodInsn method. */
+ private static class MethodVisitor5 extends MethodVisitor {
+ MethodVisitor5(final MethodVisitor methodVisitor) {
+ super(Opcodes.ASM5, methodVisitor);
+ }
+ }
+
+ /** An ASM5 {@link MethodVisitor} which overrides the ASM5 visitMethodInsn method. */
+ private static class MethodVisitor5Override extends MethodVisitor {
+
+ private final StringWriter log;
+
+ MethodVisitor5Override(final MethodVisitor methodVisitor, final StringWriter log) {
+ super(Opcodes.ASM5, methodVisitor);
+ this.log = log;
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ super.visitMethodInsn(opcode, owner, name + "5", descriptor, isInterface);
+ log.append("MethodVisitor5:" + name + descriptor + ";");
+ }
+ }
+
+ /**
+ * An ASM-like {@link MethodVisitor} subclass, which overrides the ASM5 visitMethodInsn method,
+ * but can be used with any API version.
+ */
+ private static class TraceMethodVisitor extends MethodVisitor {
+
+ protected final StringWriter log;
+
+ TraceMethodVisitor(final int api, final MethodVisitor methodVisitor, final StringWriter log) {
+ super(api, methodVisitor);
+ this.log = log;
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcodeAndSource,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
+ // Redirect the call to the deprecated version of this method.
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+ return;
+ }
+ super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
+
+ log.append("TraceMethodVisitor:" + name + descriptor + ";");
+ }
+ }
+
+ /** A user subclass of {@link TraceMethodVisitor}, implemented for ASM4. */
+ private static class UserTraceMethodVisitor4 extends TraceMethodVisitor {
+
+ UserTraceMethodVisitor4(final MethodVisitor methodVisitor, final StringWriter log) {
+ super(Opcodes.ASM4, methodVisitor, log);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ super.visitMethodInsn(opcode, owner, name, descriptor);
+ log.append("UserTraceMethodVisitor4:" + name + descriptor + ";");
+ }
+ }
+
+ /** A user subclass of {@link TraceMethodVisitor}, implemented for ASM5. */
+ private static class UserTraceMethodVisitor5 extends TraceMethodVisitor {
+
+ UserTraceMethodVisitor5(final MethodVisitor methodVisitor, final StringWriter log) {
+ super(Opcodes.ASM5, methodVisitor, log);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ log.append("UserTraceMethodVisitor5:" + name + descriptor + ";");
+ }
+ }
+
+ /** A {@link MethodVisitor} that logs the calls to its visitMethodInsn method. */
+ private static class LogMethodVisitor extends MethodVisitor {
+
+ private final StringWriter log;
+
+ LogMethodVisitor(final StringWriter log) {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+ this.log = log;
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ log.append("LogMethodVisitor:" + name + descriptor + ";");
+ }
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java b/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java
new file mode 100644
index 00000000..60ead10a
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java
@@ -0,0 +1,134 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static java.util.stream.Collectors.toSet;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link MethodWriter}.
+ *
+ * @author Eric Bruneton
+ */
+class MethodWriterTest {
+
+ /**
+ * Tests that the attribute name fields of Constants are the expected ones. This test is designed
+ * to fail each time new attributes are added to Constants, and serves as a reminder to update the
+ * {@link MethodWriter#canCopyMethodAttributes} method, if needed.
+ */
+ @Test
+ void testCanCopyMethodAttributesUpdated() {
+ Set<Object> actualAttributes =
+ Arrays.stream(Constants.class.getDeclaredFields())
+ .filter(field -> field.getType() == String.class)
+ .map(
+ field -> {
+ try {
+ return field.get(null);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new RuntimeException("Can't get field value", e);
+ }
+ })
+ .collect(toSet());
+
+ HashSet<String> expectedAttributes =
+ new HashSet<String>(
+ Arrays.asList(
+ Constants.CONSTANT_VALUE,
+ Constants.CODE,
+ Constants.STACK_MAP_TABLE,
+ Constants.EXCEPTIONS,
+ Constants.INNER_CLASSES,
+ Constants.ENCLOSING_METHOD,
+ Constants.SYNTHETIC,
+ Constants.SIGNATURE,
+ Constants.SOURCE_FILE,
+ Constants.SOURCE_DEBUG_EXTENSION,
+ Constants.LINE_NUMBER_TABLE,
+ Constants.LOCAL_VARIABLE_TABLE,
+ Constants.LOCAL_VARIABLE_TYPE_TABLE,
+ Constants.DEPRECATED,
+ Constants.RUNTIME_VISIBLE_ANNOTATIONS,
+ Constants.RUNTIME_INVISIBLE_ANNOTATIONS,
+ Constants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
+ Constants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
+ Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS,
+ Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS,
+ Constants.ANNOTATION_DEFAULT,
+ Constants.BOOTSTRAP_METHODS,
+ Constants.METHOD_PARAMETERS,
+ Constants.MODULE,
+ Constants.MODULE_PACKAGES,
+ Constants.MODULE_MAIN_CLASS,
+ Constants.NEST_HOST,
+ Constants.NEST_MEMBERS,
+ Constants.PERMITTED_SUBCLASSES,
+ Constants.RECORD));
+ // IMPORTANT: if this fails, update the list AND update MethodWriter.canCopyMethodAttributes(),
+ // if needed.
+ assertEquals(expectedAttributes, actualAttributes);
+ }
+
+ @Test
+ void testRecursiveCondyFastEnough() {
+ Handle bsm =
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "RT",
+ "bsm",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/invoke/CallSite;",
+ false);
+ ConstantDynamic chain = new ConstantDynamic("condy", "I", bsm, 0);
+ for (int i = 0; i < 32; i++) {
+ chain = new ConstantDynamic("condy" + i, "I", bsm, chain);
+ }
+ ConstantDynamic condy = chain;
+
+ assertTimeoutPreemptively(
+ Duration.ofMillis(1_000),
+ () -> {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V11, Opcodes.ACC_SUPER, "Test", null, "java/lang/Object", null);
+ MethodVisitor mv = classWriter.visitMethod(Opcodes.ACC_STATIC, "m", "()V", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(condy);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ classWriter.visitEnd();
+ classWriter.toByteArray();
+ });
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/ModuleVisitorTest.java b/asm/src/test/java/org/objectweb/asm/ModuleVisitorTest.java
new file mode 100644
index 00000000..c9eb3382
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/ModuleVisitorTest.java
@@ -0,0 +1,67 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link ModuleVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class ModuleVisitorTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new ModuleVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new ModuleVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ ModuleVisitor delegate = new ModuleVisitor(Opcodes.ASM4) {};
+ ModuleVisitor visitor = new ModuleVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/RecordComponentVisitorTest.java b/asm/src/test/java/org/objectweb/asm/RecordComponentVisitorTest.java
new file mode 100644
index 00000000..0e3ef7a3
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/RecordComponentVisitorTest.java
@@ -0,0 +1,67 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * Unit tests for {@link RecordComponentVisitor}.
+ *
+ * @author Eric Bruneton
+ */
+class RecordComponentVisitorTest {
+
+ @Test
+ void testConstructor_validApi() {
+ Executable constructor = () -> new RecordComponentVisitor(Opcodes.ASM4) {};
+
+ assertDoesNotThrow(constructor);
+ }
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new RecordComponentVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+
+ @Test
+ void testGetDelegate() {
+ RecordComponentVisitor delegate = new RecordComponentVisitor(Opcodes.ASM4) {};
+ RecordComponentVisitor visitor = new RecordComponentVisitor(Opcodes.ASM4, delegate) {};
+
+ assertSame(delegate, visitor.getDelegate());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/TypePathTest.java b/asm/src/test/java/org/objectweb/asm/TypePathTest.java
new file mode 100644
index 00000000..4bf3b588
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/TypePathTest.java
@@ -0,0 +1,76 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link TypePath}.
+ *
+ * @author Eric Bruneton
+ */
+class TypePathTest {
+
+ /** Tests that {@link TypePath#getLength()} returns correct values. */
+ @Test
+ void testGetLength() {
+ assertEquals(5, TypePath.fromString("[.[*0").getLength());
+ assertEquals(5, TypePath.fromString("[*0;*[").getLength());
+ assertEquals(1, TypePath.fromString("10;").getLength());
+ assertEquals(2, TypePath.fromString("1;0;").getLength());
+ }
+
+ /** Tests that {@link TypePath#getStep(int)} returns correct values. */
+ @Test
+ void testGetStep() {
+ TypePath typePath = TypePath.fromString("[.[*7");
+
+ assertEquals(TypePath.ARRAY_ELEMENT, typePath.getStep(0));
+ assertEquals(TypePath.INNER_TYPE, typePath.getStep(1));
+ assertEquals(TypePath.WILDCARD_BOUND, typePath.getStep(3));
+ assertEquals(TypePath.TYPE_ARGUMENT, typePath.getStep(4));
+ assertEquals(7, typePath.getStepArgument(4));
+ }
+
+ /** Tests that type paths are unchanged via a fromString -> toString transform. */
+ @Test
+ void testFromAndToString() {
+ assertEquals(null, TypePath.fromString(null));
+ assertEquals(null, TypePath.fromString(""));
+ assertEquals("[.[*0;", TypePath.fromString("[.[*0").toString());
+ assertEquals("[*0;*[", TypePath.fromString("[*0;*[").toString());
+ assertEquals("10;", TypePath.fromString("10;").toString());
+ assertEquals("1;0;", TypePath.fromString("1;0;").toString());
+ assertThrows(IllegalArgumentException.class, () -> TypePath.fromString("-"));
+ assertThrows(IllegalArgumentException.class, () -> TypePath.fromString("="));
+ assertThrows(IllegalArgumentException.class, () -> TypePath.fromString("1-"));
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/TypeReferenceTest.java b/asm/src/test/java/org/objectweb/asm/TypeReferenceTest.java
new file mode 100644
index 00000000..2c12fd9a
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/TypeReferenceTest.java
@@ -0,0 +1,107 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link TypeReference}.
+ *
+ * @author Eric Bruneton
+ */
+class TypeReferenceTest {
+
+ @Test
+ void testNewTypeReference() {
+ TypeReference typeReference = TypeReference.newTypeReference(TypeReference.FIELD);
+
+ assertEquals(TypeReference.FIELD, typeReference.getSort());
+ assertEquals(TypeReference.FIELD << 24, typeReference.getValue());
+ }
+
+ @Test
+ void testNewTypeParameterReference() {
+ TypeReference typeReference =
+ TypeReference.newTypeParameterReference(TypeReference.CLASS_TYPE_PARAMETER, 3);
+
+ assertEquals(TypeReference.CLASS_TYPE_PARAMETER, typeReference.getSort());
+ assertEquals(3, typeReference.getTypeParameterIndex());
+ }
+
+ @Test
+ void testNewTypeParameterBoundReference() {
+ TypeReference typeReference =
+ TypeReference.newTypeParameterBoundReference(TypeReference.CLASS_TYPE_PARAMETER, 3, 7);
+
+ assertEquals(TypeReference.CLASS_TYPE_PARAMETER, typeReference.getSort());
+ assertEquals(3, typeReference.getTypeParameterIndex());
+ assertEquals(7, typeReference.getTypeParameterBoundIndex());
+ }
+
+ @Test
+ void testNewSuperTypeReference() {
+ TypeReference typeReference = TypeReference.newSuperTypeReference(-1);
+
+ assertEquals(TypeReference.CLASS_EXTENDS, typeReference.getSort());
+ assertEquals(-1, typeReference.getSuperTypeIndex());
+ }
+
+ @Test
+ void testNewFormalParameterReference() {
+ TypeReference typeReference = TypeReference.newFormalParameterReference(3);
+
+ assertEquals(TypeReference.METHOD_FORMAL_PARAMETER, typeReference.getSort());
+ assertEquals(3, typeReference.getFormalParameterIndex());
+ }
+
+ @Test
+ void testNewExceptionReference() {
+ TypeReference typeReference = TypeReference.newExceptionReference(3);
+
+ assertEquals(TypeReference.THROWS, typeReference.getSort());
+ assertEquals(3, typeReference.getExceptionIndex());
+ }
+
+ @Test
+ void testNewTryCatchReference() {
+ TypeReference typeReference = TypeReference.newTryCatchReference(3);
+
+ assertEquals(TypeReference.EXCEPTION_PARAMETER, typeReference.getSort());
+ assertEquals(3, typeReference.getTryCatchBlockIndex());
+ }
+
+ @Test
+ void testNewTypeArgumentReference() {
+ TypeReference typeReference = TypeReference.newTypeArgumentReference(TypeReference.CAST, 3);
+
+ assertEquals(TypeReference.CAST, typeReference.getSort());
+ assertEquals(3, typeReference.getTypeArgumentIndex());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/TypeTest.java b/asm/src/test/java/org/objectweb/asm/TypeTest.java
new file mode 100644
index 00000000..bf52bcd2
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/TypeTest.java
@@ -0,0 +1,434 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.time.Duration;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+/**
+ * Unit tests for {@link Type}.
+ *
+ * @author Eric Bruneton
+ */
+class TypeTest implements Opcodes {
+
+ @Test
+ void testGetSort_typeConstants() {
+ assertEquals(Type.VOID, Type.VOID_TYPE.getSort());
+ assertEquals(Type.BOOLEAN, Type.BOOLEAN_TYPE.getSort());
+ assertEquals(Type.CHAR, Type.CHAR_TYPE.getSort());
+ assertEquals(Type.BYTE, Type.BYTE_TYPE.getSort());
+ assertEquals(Type.SHORT, Type.SHORT_TYPE.getSort());
+ assertEquals(Type.INT, Type.INT_TYPE.getSort());
+ assertEquals(Type.FLOAT, Type.FLOAT_TYPE.getSort());
+ assertEquals(Type.LONG, Type.LONG_TYPE.getSort());
+ assertEquals(Type.DOUBLE, Type.DOUBLE_TYPE.getSort());
+ }
+
+ @Test
+ void testGetSize_typeConstants() {
+ assertEquals(0, Type.VOID_TYPE.getSize());
+ assertEquals(1, Type.BOOLEAN_TYPE.getSize());
+ assertEquals(1, Type.CHAR_TYPE.getSize());
+ assertEquals(1, Type.BYTE_TYPE.getSize());
+ assertEquals(1, Type.SHORT_TYPE.getSize());
+ assertEquals(1, Type.INT_TYPE.getSize());
+ assertEquals(1, Type.FLOAT_TYPE.getSize());
+ assertEquals(2, Type.LONG_TYPE.getSize());
+ assertEquals(2, Type.DOUBLE_TYPE.getSize());
+ }
+
+ @Test
+ void testGetDescriptor_typeConstants() {
+ assertEquals("V", Type.VOID_TYPE.getDescriptor());
+ assertEquals("Z", Type.BOOLEAN_TYPE.getDescriptor());
+ assertEquals("C", Type.CHAR_TYPE.getDescriptor());
+ assertEquals("B", Type.BYTE_TYPE.getDescriptor());
+ assertEquals("S", Type.SHORT_TYPE.getDescriptor());
+ assertEquals("I", Type.INT_TYPE.getDescriptor());
+ assertEquals("F", Type.FLOAT_TYPE.getDescriptor());
+ assertEquals("J", Type.LONG_TYPE.getDescriptor());
+ assertEquals("J", Type.LONG_TYPE.getDescriptor());
+ assertEquals("D", Type.DOUBLE_TYPE.getDescriptor());
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "I",
+ "V",
+ "Z",
+ "B",
+ "C",
+ "S",
+ "D",
+ "F",
+ "J",
+ "LI;",
+ "LV;",
+ "Ljava/lang/Object;",
+ "[I",
+ "[LI;",
+ "[[Ljava/lang/Object;",
+ "(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V",
+ "()I",
+ "()LI;",
+ "()Ljava/lang/Object;",
+ "()[I",
+ "()[LI;",
+ "()[[Ljava/lang/Object;"
+ })
+ void testGetTypeFromDescriptor(final String descriptor) {
+ Type type = Type.getType(descriptor);
+
+ assertEquals(descriptor, type.getDescriptor());
+ assertEquals(descriptor, type.toString());
+ }
+
+ @Test
+ void testGetTypeFromDescriptor_invalid() {
+ Executable getType = () -> Type.getType("-");
+
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, getType);
+ assertEquals("Invalid descriptor: -", exception.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"I", "V", "java/lang/Object", "[I", "[LI;", "[[Ljava/lang/Object;"})
+ void testGetObjectType(final String internalName) {
+ Type type = Type.getObjectType(internalName);
+
+ assertEquals(internalName, type.getInternalName());
+ assertEquals(internalName.charAt(0) == '[' ? Type.ARRAY : Type.OBJECT, type.getSort());
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V",
+ "()I",
+ "()LI;",
+ "()Ljava/lang/Object;",
+ "()[I",
+ "()[LI;",
+ "()[[Ljava/lang/Object;"
+ })
+ void testGetMethodTypeFromDescriptor(final String methodDescriptor) {
+ Type type = Type.getMethodType(methodDescriptor);
+
+ assertEquals(Type.METHOD, type.getSort());
+ assertEquals(methodDescriptor, type.getDescriptor());
+ assertEquals(methodDescriptor, type.toString());
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V",
+ "()I",
+ "()LI;",
+ "()Ljava/lang/Object;",
+ "()[I",
+ "()[LI;",
+ "()[[Ljava/lang/Object;"
+ })
+ void testGetArgumentTypesGetReturnTypeAndGetMethodType(final String methodDescriptor) {
+ Type[] argumentTypes = Type.getArgumentTypes(methodDescriptor);
+ Type returnType = Type.getReturnType(methodDescriptor);
+ Type methodType = Type.getMethodType(returnType, argumentTypes);
+
+ assertEquals(Type.METHOD, methodType.getSort());
+ assertEquals(methodDescriptor, methodType.getDescriptor());
+ assertArrayEquals(argumentTypes, methodType.getArgumentTypes());
+ assertEquals(returnType, methodType.getReturnType());
+ }
+
+ @Test
+ void testGetArgumentTypesInvalidMethodDescriptor() {
+ Executable getArgumentTypes = () -> Type.getArgumentTypes("(Ljava/lang/String");
+
+ assertTimeoutPreemptively(
+ Duration.ofMillis(100), () -> assertThrows(RuntimeException.class, getArgumentTypes));
+ }
+
+ @Test
+ void testGetArgumentTypesInvalidArgumentDescriptor() {
+ Executable getArgumentTypes = () -> Type.getArgumentTypes("(Ljava/lang/String;-)V");
+
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, getArgumentTypes);
+ assertEquals("Invalid descriptor: (Ljava/lang/String;-)V", exception.getMessage());
+ }
+
+ @Test
+ void testGetReturnTypeFromDescriptor() {
+ assertEquals(Type.INT_TYPE, Type.getReturnType("()I"));
+ assertEquals(Type.INT_TYPE, Type.getReturnType("(Lpkg/classMethod();)I"));
+ }
+
+ @Test
+ void testGetTypeFromClass() {
+ assertEquals(Type.VOID_TYPE, Type.getType(void.class));
+ assertEquals(Type.BOOLEAN_TYPE, Type.getType(boolean.class));
+ assertEquals(Type.CHAR_TYPE, Type.getType(char.class));
+ assertEquals(Type.BYTE_TYPE, Type.getType(byte.class));
+ assertEquals(Type.SHORT_TYPE, Type.getType(short.class));
+ assertEquals(Type.INT_TYPE, Type.getType(int.class));
+ assertEquals(Type.FLOAT_TYPE, Type.getType(float.class));
+ assertEquals(Type.LONG_TYPE, Type.getType(long.class));
+ assertEquals(Type.DOUBLE_TYPE, Type.getType(double.class));
+ assertEquals("Ljava/lang/Object;", Type.getType(Object.class).getDescriptor());
+ assertEquals("[Ljava/lang/Object;", Type.getType(Object[].class).getDescriptor());
+ }
+
+ @Test
+ void testGetTypeFromConstructor() throws NoSuchMethodException, SecurityException {
+ Type type = Type.getType(ClassReader.class.getConstructor(byte[].class, int.class, int.class));
+
+ assertEquals("([BII)V", type.getDescriptor());
+ }
+
+ @Test
+ void testGetTypeFromMethod() throws NoSuchMethodException, SecurityException {
+ Type type = Type.getType(Arrays.class.getMethod("binarySearch", byte[].class, byte.class));
+
+ assertEquals("([BB)I", type.getDescriptor());
+ }
+
+ @Test
+ void testGetArgumentTypesFromMethod() throws NoSuchMethodException, SecurityException {
+ Type[] argumentTypes =
+ Type.getArgumentTypes(Arrays.class.getMethod("binarySearch", byte[].class, byte.class));
+
+ assertArrayEquals(new Type[] {Type.getType(byte[].class), Type.BYTE_TYPE}, argumentTypes);
+ }
+
+ @Test
+ void testGetReturnTypeFromMethod() throws NoSuchMethodException, SecurityException {
+ Type returnType =
+ Type.getReturnType(Arrays.class.getMethod("binarySearch", byte[].class, byte.class));
+
+ assertEquals(Type.INT_TYPE, returnType);
+ }
+
+ @Test
+ void testGetArgumentsAndReturnSizeFromDescriptor() {
+ assertEquals(
+ 17 << 2,
+ Type.getArgumentsAndReturnSizes(
+ "(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V"));
+ assertEquals(1 << 2 | 1, Type.getArgumentsAndReturnSizes("()I"));
+ assertEquals(1 << 2 | 1, Type.getArgumentsAndReturnSizes("()F"));
+ assertEquals(1 << 2 | 2, Type.getArgumentsAndReturnSizes("()J"));
+ assertEquals(1 << 2 | 2, Type.getArgumentsAndReturnSizes("()D"));
+ assertEquals(1 << 2 | 1, Type.getArgumentsAndReturnSizes("()LD;"));
+ }
+
+ @Test
+ void testGetSort() {
+ assertEquals(Type.ARRAY, Type.getType("[LI;").getSort());
+ assertEquals(Type.ARRAY, Type.getObjectType("[LI;").getSort());
+ assertEquals(Type.OBJECT, Type.getType("LI;").getSort());
+ assertEquals(Type.OBJECT, Type.getObjectType("I").getSort());
+ }
+
+ @Test
+ void testGetDimensions() {
+ assertEquals(1, Type.getType("[I").getDimensions());
+ assertEquals(3, Type.getType("[[[LI;").getDimensions());
+ }
+
+ @Test
+ void testGetElementType() {
+ assertEquals(Type.INT_TYPE, Type.getType("[I").getElementType());
+ assertEquals(Type.getObjectType("I"), Type.getType("[[[LI;").getElementType());
+ }
+
+ @Test
+ void testGetClassName() {
+ assertEquals("void", Type.VOID_TYPE.getClassName());
+ assertEquals("boolean", Type.BOOLEAN_TYPE.getClassName());
+ assertEquals("char", Type.CHAR_TYPE.getClassName());
+ assertEquals("byte", Type.BYTE_TYPE.getClassName());
+ assertEquals("short", Type.SHORT_TYPE.getClassName());
+ assertEquals("int", Type.INT_TYPE.getClassName());
+ assertEquals("float", Type.FLOAT_TYPE.getClassName());
+ assertEquals("long", Type.LONG_TYPE.getClassName());
+ assertEquals("double", Type.DOUBLE_TYPE.getClassName());
+ assertEquals("I[]", Type.getObjectType("[LI;").getClassName());
+ assertEquals("java.lang.Object", Type.getObjectType("java/lang/Object").getClassName());
+ assertEquals("java.lang.Object", Type.getType("Ljava/lang/Object;").getClassName());
+ }
+
+ @Test
+ void testGetInternalName() {
+ assertEquals("[LI;", Type.getObjectType("[LI;").getInternalName());
+ assertEquals("java/lang/Object", Type.getObjectType("java/lang/Object").getInternalName());
+ assertEquals("java/lang/Object", Type.getType("Ljava/lang/Object;").getInternalName());
+ }
+
+ @Test
+ void testGetArgumentsAndReturnSize() {
+ Type type = Type.getType("(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V");
+
+ assertEquals(17 << 2, type.getArgumentsAndReturnSizes());
+ }
+
+ @Test
+ void testGetDescriptor() {
+ assertEquals("[LI;", Type.getObjectType("[LI;").getDescriptor());
+ assertEquals("Ljava/lang/Object;", Type.getObjectType("java/lang/Object").getDescriptor());
+ assertEquals("Ljava/lang/Object;", Type.getType("Ljava/lang/Object;").getDescriptor());
+ }
+
+ @Test
+ void testGetMethodDescriptor() {
+ assertEquals("(IJ)V", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.LONG_TYPE));
+ assertEquals(
+ "(Ljava/lang/Object;)V",
+ Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType("Ljava/lang/Object;")));
+ assertEquals(
+ "(Ljava/lang/Object;)V",
+ Type.getMethodDescriptor(Type.VOID_TYPE, Type.getObjectType("java/lang/Object")));
+ }
+
+ @Test
+ void testGetInternalNameFromClass() {
+ assertEquals("java/lang/Object", Type.getInternalName(Object.class));
+ assertEquals("[Ljava/lang/Object;", Type.getInternalName(Object[].class));
+ }
+
+ @Test
+ void testGetDescriptorFromClass() {
+ assertEquals("V", Type.getDescriptor(void.class));
+ assertEquals("Z", Type.getDescriptor(boolean.class));
+ assertEquals("C", Type.getDescriptor(char.class));
+ assertEquals("B", Type.getDescriptor(byte.class));
+ assertEquals("S", Type.getDescriptor(short.class));
+ assertEquals("I", Type.getDescriptor(int.class));
+ assertEquals("F", Type.getDescriptor(float.class));
+ assertEquals("J", Type.getDescriptor(long.class));
+ assertEquals("D", Type.getDescriptor(double.class));
+ assertEquals("Ljava/lang/Object;", Type.getDescriptor(Object.class));
+ assertEquals("[Ljava/lang/Object;", Type.getDescriptor(Object[].class));
+ assertEquals("[[Ljava/lang/Object;", Type.getDescriptor(Object[][].class));
+ assertEquals("[[I", Type.getDescriptor(int[][].class));
+ }
+
+ @Test
+ void testGetOpcode() {
+ assertEquals(BALOAD, Type.BOOLEAN_TYPE.getOpcode(IALOAD));
+ assertEquals(BALOAD, Type.BYTE_TYPE.getOpcode(IALOAD));
+ assertEquals(CALOAD, Type.CHAR_TYPE.getOpcode(IALOAD));
+ assertEquals(SALOAD, Type.SHORT_TYPE.getOpcode(IALOAD));
+ assertEquals(IALOAD, Type.INT_TYPE.getOpcode(IALOAD));
+ assertEquals(FALOAD, Type.FLOAT_TYPE.getOpcode(IALOAD));
+ assertEquals(LALOAD, Type.LONG_TYPE.getOpcode(IALOAD));
+ assertEquals(DALOAD, Type.DOUBLE_TYPE.getOpcode(IALOAD));
+ assertEquals(AALOAD, Type.getType("Ljava/lang/Object;").getOpcode(IALOAD));
+ assertEquals(AALOAD, Type.getObjectType("java/lang/Object").getOpcode(IALOAD));
+ assertEquals(AASTORE, Type.getType("Ljava/lang/Object;").getOpcode(IASTORE));
+ assertEquals(AASTORE, Type.getObjectType("java/lang/Object").getOpcode(IASTORE));
+ assertEquals(AASTORE, Type.getType("[I").getOpcode(IASTORE));
+ assertEquals(RETURN, Type.VOID_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(IRETURN, Type.BOOLEAN_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(IRETURN, Type.BYTE_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(IRETURN, Type.CHAR_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(IRETURN, Type.SHORT_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(IRETURN, Type.INT_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(FRETURN, Type.FLOAT_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(LRETURN, Type.LONG_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(DRETURN, Type.DOUBLE_TYPE.getOpcode(Opcodes.IRETURN));
+ assertEquals(ARETURN, Type.getType("Ljava/lang/Object;").getOpcode(Opcodes.IRETURN));
+ assertEquals(ARETURN, Type.getObjectType("java/lang/Object").getOpcode(Opcodes.IRETURN));
+ assertEquals(ARETURN, Type.getType("Ljava/lang/Object;").getOpcode(Opcodes.IRETURN));
+ assertEquals(ARETURN, Type.getObjectType("java/lang/Object").getOpcode(Opcodes.IRETURN));
+ assertEquals(ARETURN, Type.getType("[I").getOpcode(Opcodes.IRETURN));
+ assertEquals(IADD, Type.BOOLEAN_TYPE.getOpcode(IADD));
+ assertEquals(IADD, Type.BYTE_TYPE.getOpcode(IADD));
+ assertEquals(IADD, Type.CHAR_TYPE.getOpcode(IADD));
+ assertEquals(IADD, Type.SHORT_TYPE.getOpcode(IADD));
+ assertEquals(IADD, Type.INT_TYPE.getOpcode(IADD));
+ assertEquals(FADD, Type.FLOAT_TYPE.getOpcode(IADD));
+ assertEquals(LADD, Type.LONG_TYPE.getOpcode(IADD));
+ assertEquals(DADD, Type.DOUBLE_TYPE.getOpcode(IADD));
+ Class<UnsupportedOperationException> expectedException = UnsupportedOperationException.class;
+ assertThrows(expectedException, () -> Type.VOID_TYPE.getOpcode(IADD));
+ assertThrows(expectedException, () -> Type.VOID_TYPE.getOpcode(ILOAD));
+ assertThrows(expectedException, () -> Type.VOID_TYPE.getOpcode(IALOAD));
+ assertThrows(expectedException, () -> Type.getType("LI;").getOpcode(IADD));
+ assertThrows(expectedException, () -> Type.getType("[I").getOpcode(IADD));
+ assertThrows(expectedException, () -> Type.getObjectType("I").getOpcode(IADD));
+ assertThrows(expectedException, () -> Type.getMethodType("()V").getOpcode(IADD));
+ assertThrows(expectedException, () -> Type.getMethodType("()V").getOpcode(IALOAD));
+ }
+
+ @Test
+ void testEquals() {
+ Type nullType = null;
+
+ final boolean equalsNull = Type.getObjectType("I").equals(nullType);
+ final boolean equalsDifferentTypeSort = Type.getObjectType("I").equals(Type.INT_TYPE);
+ final boolean equalsDifferentObjectType =
+ Type.getObjectType("I").equals(Type.getObjectType("HI"));
+ final boolean equalsOtherDifferentObjectType =
+ Type.getObjectType("I").equals(Type.getObjectType("J"));
+ final boolean equalsSameType = Type.getObjectType("I").equals(Type.getType("LI;"));
+ final boolean equalsSameObjectType = Type.getType("LI;").equals(Type.getObjectType("I"));
+ final boolean equalsSamePrimitiveType = Type.INT_TYPE.equals(Type.getType("I"));
+
+ assertFalse(equalsNull);
+ assertFalse(equalsDifferentTypeSort);
+ assertFalse(equalsDifferentObjectType);
+ assertFalse(equalsOtherDifferentObjectType);
+ assertTrue(equalsSameType);
+ assertTrue(equalsSameObjectType);
+ assertTrue(equalsSamePrimitiveType);
+ }
+
+ @Test
+ void testHashcode() {
+ assertNotEquals(0, Type.getType("Ljava/lang/Object;").hashCode());
+ assertEquals(
+ Type.getType("Ljava/lang/Object;").hashCode(),
+ Type.getObjectType("java/lang/Object").hashCode());
+ assertNotEquals(Type.INT_TYPE.hashCode(), Type.getObjectType("I").hashCode());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java b/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java
new file mode 100644
index 00000000..2ce111b2
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * SignatureReader tests.
+ *
+ * @author Eric Bruneton
+ */
+class SignatureReaderTest extends AsmTest {
+
+ @ParameterizedTest
+ @MethodSource({
+ "org.objectweb.asm.signature.SignaturesProviders#classSignatures",
+ "org.objectweb.asm.signature.SignaturesProviders#methodSignatures"
+ })
+ void testAccept_validClassOrMethodSignature(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureVisitor signatureVisitor =
+ new SignatureVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {};
+
+ Executable acceptVisitor = () -> signatureReader.accept(signatureVisitor);
+
+ assertDoesNotThrow(acceptVisitor);
+ }
+
+ @ParameterizedTest
+ @MethodSource("org.objectweb.asm.signature.SignaturesProviders#fieldSignatures")
+ void testAccept_validFieldSignature(final String signature) {
+ SignatureReader signatureReader = new SignatureReader(signature);
+ SignatureVisitor signatureVisitor =
+ new SignatureVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {};
+
+ Executable acceptVisitor = () -> signatureReader.acceptType(signatureVisitor);
+
+ assertDoesNotThrow(acceptVisitor);
+ }
+
+ @Test
+ void testAccept_invalidSignature() {
+ String invalidSignature = "-";
+ SignatureReader signatureReader = new SignatureReader(invalidSignature);
+ SignatureVisitor signatureVisitor =
+ new SignatureVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) {};
+
+ Executable acceptVisitor = () -> signatureReader.accept(signatureVisitor);
+
+ assertThrows(IllegalArgumentException.class, acceptVisitor);
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignatureVisitorTest.java b/asm/src/test/java/org/objectweb/asm/signature/SignatureVisitorTest.java
new file mode 100644
index 00000000..7a186199
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignatureVisitorTest.java
@@ -0,0 +1,50 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+
+/**
+ * SignatureVisitor tests.
+ *
+ * @author Eric Bruneton
+ */
+class SignatureVisitorTest {
+
+ @Test
+ void testConstructor_invalidApi() {
+ Executable constructor = () -> new SignatureVisitor(0) {};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, constructor);
+ assertEquals("Unsupported api 0", exception.getMessage());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java b/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java
new file mode 100644
index 00000000..be1ba012
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignatureWriterTest.java
@@ -0,0 +1,65 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.signature;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.objectweb.asm.test.AsmTest;
+
+/**
+ * SignatureWriter tests.
+ *
+ * @author Eric Bruneton
+ */
+class SignatureWriterTest extends AsmTest {
+
+ @ParameterizedTest
+ @MethodSource({
+ "org.objectweb.asm.signature.SignaturesProviders#classSignatures",
+ "org.objectweb.asm.signature.SignaturesProviders#methodSignatures"
+ })
+ void testReadAndWrite_classOrMethodSignature(final String signature) {
+ SignatureWriter signatureWriter = new SignatureWriter();
+
+ new SignatureReader(signature).accept(signatureWriter);
+
+ assertEquals(signature, signatureWriter.toString());
+ }
+
+ @ParameterizedTest
+ @MethodSource("org.objectweb.asm.signature.SignaturesProviders#fieldSignatures")
+ void testReadAndWrite_fieldSignature(final String signature) {
+ SignatureWriter signatureWriter = new SignatureWriter();
+
+ new SignatureReader(signature).acceptType(signatureWriter);
+
+ assertEquals(signature, signatureWriter.toString());
+ }
+}
diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java
new file mode 100644
index 00000000..650db55f
--- /dev/null
+++ b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java
@@ -0,0 +1,111 @@
+package org.objectweb.asm.signature;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.test.AsmTest;
+import org.objectweb.asm.test.AsmTest.PrecompiledClass;
+
+/**
+ * Provides class, field and method signatures for parameterized unit tests.
+ *
+ * @author Eric Bruneton
+ */
+public final class SignaturesProviders {
+
+ private static final List<String> CLASS_SIGNATURES = new ArrayList<>();
+ private static final List<String> FIELD_SIGNATURES = new ArrayList<>();
+ private static final List<String> METHOD_SIGNATURES = new ArrayList<>();
+
+ static {
+ AsmTest.allClassesAndLatestApi()
+ .map(argument -> (PrecompiledClass) argument.get()[0])
+ .filter(precompiledClass -> !precompiledClass.isMoreRecentThan(AsmTest.Api.ASM7))
+ .forEach(precompiledClass -> collectSignatures(precompiledClass));
+ assertFalse(CLASS_SIGNATURES.isEmpty());
+ assertFalse(FIELD_SIGNATURES.isEmpty());
+ assertFalse(METHOD_SIGNATURES.isEmpty());
+ for (int depth = 0; depth < 48; ++depth) {
+ FIELD_SIGNATURES.add(buildDeepSignature(new StringBuilder(), depth).toString());
+ }
+ }
+
+ private SignaturesProviders() {}
+
+ private static void collectSignatures(final PrecompiledClass classParameter) {
+ ClassReader classReader = new ClassReader(classParameter.getBytes());
+ classReader.accept(
+ new ClassVisitor(/*latest api */ Opcodes.ASM9) {
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if (signature != null) {
+ CLASS_SIGNATURES.add(signature);
+ }
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ if (signature != null) {
+ FIELD_SIGNATURES.add(signature);
+ }
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ if (signature != null) {
+ METHOD_SIGNATURES.add(signature);
+ }
+ return null;
+ }
+ },
+ 0);
+ }
+
+ private static StringBuilder buildDeepSignature(final StringBuilder signature, final int depth) {
+ signature.append("LGeneric");
+ if (depth == 0) {
+ signature.append(';');
+ } else {
+ signature.append("<LOpen;");
+ buildDeepSignature(signature, depth - 1);
+ signature.append("LClose;>;");
+ }
+ return signature;
+ }
+
+ static Stream<String> classSignatures() {
+ return CLASS_SIGNATURES.stream();
+ }
+
+ static Stream<String> fieldSignatures() {
+ return FIELD_SIGNATURES.stream();
+ }
+
+ static Stream<String> methodSignatures() {
+ return METHOD_SIGNATURES.stream();
+ }
+}
diff --git a/asm/src/test/resources/Issue307600.class b/asm/src/test/resources/Issue307600.class
new file mode 100644
index 00000000..16134b66
--- /dev/null
+++ b/asm/src/test/resources/Issue307600.class
Binary files differ
diff --git a/asm/src/test/resources/Issue311642.class b/asm/src/test/resources/Issue311642.class
new file mode 100644
index 00000000..11dd3eca
--- /dev/null
+++ b/asm/src/test/resources/Issue311642.class
Binary files differ
diff --git a/asm/src/test/resources/sigtest-4.0.txt b/asm/src/test/resources/sigtest-4.0.txt
new file mode 100644
index 00000000..0f413dc7
--- /dev/null
+++ b/asm/src/test/resources/sigtest-4.0.txt
@@ -0,0 +1,515 @@
+#Signature file v4.1
+#Version 4.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds a,c,d
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds A,B,C,D,E,G,H,I,J,K,L,M,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+meth public boolean equals(java.lang.Object)
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d,e,f,g,h,i,j,k
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor)
+meth public static java.lang.String getDescriptor(java.lang.Class)
+meth public static java.lang.String getInternalName(java.lang.Class)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds a,b,c,d
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds a
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds a,b,c,d
+
diff --git a/asm/src/test/resources/sigtest-5.0.txt b/asm/src/test/resources/sigtest-5.0.txt
new file mode 100644
index 00000000..6da6b60c
--- /dev/null
+++ b/asm/src/test/resources/sigtest-5.0.txt
@@ -0,0 +1,584 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds a,c,d
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds A,B,C,D,E,G,H,I,J,K,L,M,N,O,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+meth public boolean equals(java.lang.Object)
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d,e,f,g,h,i,j,k
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor)
+meth public static java.lang.String getDescriptor(java.lang.Class)
+meth public static java.lang.String getInternalName(java.lang.Class)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds a,b,c,d
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds a
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds a
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds a,b,c,d
+
diff --git a/asm/src/test/resources/sigtest-5.1.txt b/asm/src/test/resources/sigtest-5.1.txt
new file mode 100644
index 00000000..73e078e0
--- /dev/null
+++ b/asm/src/test/resources/sigtest-5.1.txt
@@ -0,0 +1,587 @@
+#Signature file v4.1
+#Version 5.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds a,c,d
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds A,B,C,D,E,G,H,I,J,K,L,M,N,O,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d,e
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds a,b,c,d,e,f,g,h,i,j,k
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor)
+meth public static java.lang.String getDescriptor(java.lang.Class)
+meth public static java.lang.String getInternalName(java.lang.Class)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds a,b,c,d
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds a,b
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds a
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds a
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds a,b,c,d
+
diff --git a/asm/src/test/resources/sigtest-6.0.txt b/asm/src/test/resources/sigtest-6.0.txt
new file mode 100644
index 00000000..e7a5f56a
--- /dev/null
+++ b/asm/src/test/resources/sigtest-6.0.txt
@@ -0,0 +1,617 @@
+#Signature file v4.1
+#Version 6.0
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds next,value
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,items,maxStringLength,strings
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds ACC_SYNTHETIC_ATTRIBUTE,ASM_LABELW_INSN,ASM_LABEL_INSN,BSM,CLASS,DOUBLE,FIELD,FIELDORMETH_INSN,FLOAT,F_INSERT,HANDLE,HANDLE_BASE,IINC_INSN,IMETH,IMPLVAR_INSN,INDY,INDYMETH_INSN,INT,ITFMETH_INSN,LABELW_INSN,LABEL_INSN,LDCW_INSN,LDC_INSN,LONG,LOOK_INSN,MANA_INSN,METH,MODULE,MTYPE,NAME_TYPE,NOARG_INSN,PACKAGE,SBYTE_INSN,SHORT_INSN,STR,TABL_INSN,TO_ACC_SYNTHETIC,TYPE,TYPE_INSN,TYPE_MERGED,TYPE_NORMAL,TYPE_UNINIT,UTF8,VAR_INSN,WIDE_INSN,access,anns,attrs,bootstrapMethods,bootstrapMethodsCount,compute,cr,enclosingMethod,enclosingMethodOwner,firstField,firstMethod,hasAsmInsns,ianns,index,innerClasses,innerClassesCount,interfaceCount,interfaces,itanns,items,key,key2,key3,key4,lastField,lastMethod,moduleWriter,name,pool,signature,sourceDebug,sourceFile,superName,tanns,thisName,threshold,typeCount,typeTable,version
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds desc,itf,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds DEBUG,JSR,PUSHED,REACHABLE,RESIZED,RESOLVED,RET,STORE,SUBROUTINE,TARGET,VISITED,VISITED2,frame,inputStackTop,line,next,outputStackMax,position,referenceCount,srcAndRefPositions,status,successor,successors
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+ anno 0 java.lang.Deprecated()
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds buf,len,off,sort
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds b,offset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds value
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signature
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,buf,hasFormals,hasParameters
+
diff --git a/asm/src/test/resources/sigtest-6.1.txt b/asm/src/test/resources/sigtest-6.1.txt
new file mode 100644
index 00000000..1ad1285f
--- /dev/null
+++ b/asm/src/test/resources/sigtest-6.1.txt
@@ -0,0 +1,618 @@
+#Signature file v4.1
+#Version 6.1
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,classes,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,interfaceCount,interfaces,lastField,lastMethod,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,numberOfClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_BODY,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,VALUES_CAPACITY_INCREMENT,bytecodeOffset,flags,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,valueCount,values
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBuffer,valueLength,valueOffset
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-6.2.txt b/asm/src/test/resources/sigtest-6.2.txt
new file mode 100644
index 00000000..dfc364e2
--- /dev/null
+++ b/asm/src/test/resources/sigtest-6.2.txt
@@ -0,0 +1,629 @@
+#Signature file v4.1
+#Version 6.2
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,cpInfoOffsets,cpInfoValues,maxStringLength
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-7.0.txt b/asm/src/test/resources/sigtest-7.0.txt
new file mode 100644
index 00000000..108d281a
--- /dev/null
+++ b/asm/src/test/resources/sigtest-7.0.txt
@@ -0,0 +1,708 @@
+#Signature file v4.1
+#Version 7.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-7.1.txt b/asm/src/test/resources/sigtest-7.1.txt
new file mode 100644
index 00000000..e940d75d
--- /dev/null
+++ b/asm/src/test/resources/sigtest-7.1.txt
@@ -0,0 +1,711 @@
+#Signature file v4.1
+#Version 7.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-7.2.txt b/asm/src/test/resources/sigtest-7.2.txt
new file mode 100644
index 00000000..959f4bbf
--- /dev/null
+++ b/asm/src/test/resources/sigtest-7.2.txt
@@ -0,0 +1,712 @@
+#Signature file v4.1
+#Version 7.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-7.3.1.txt b/asm/src/test/resources/sigtest-7.3.1.txt
new file mode 100644
index 00000000..e7ac0cf6
--- /dev/null
+++ b/asm/src/test/resources/sigtest-7.3.1.txt
@@ -0,0 +1,729 @@
+#Signature file v4.1
+#Version 7.3.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public abstract interface !annotation java.lang.Deprecated
+intf java.lang.annotation.Annotation
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface java.lang.annotation.Annotation
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
+meth public abstract java.lang.String toString()
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubtypeClasses,permittedSubtypeClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+supr java.lang.Object
+hfds delegate
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-8.0.1.txt b/asm/src/test/resources/sigtest-8.0.1.txt
new file mode 100644
index 00000000..8c0b322f
--- /dev/null
+++ b/asm/src/test/resources/sigtest-8.0.1.txt
@@ -0,0 +1,729 @@
+#Signature file v4.1
+#Version 8.0.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubtypeClasses,permittedSubtypeClasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-9.0.txt b/asm/src/test/resources/sigtest-9.0.txt
new file mode 100644
index 00000000..cde9fa2d
--- /dev/null
+++ b/asm/src/test/resources/sigtest-9.0.txt
@@ -0,0 +1,733 @@
+#Signature file v4.1
+#Version 9.0
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitPermittedSubclass(java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubclasses,permittedSubclasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-9.1.txt b/asm/src/test/resources/sigtest-9.1.txt
new file mode 100644
index 00000000..4072e451
--- /dev/null
+++ b/asm/src/test/resources/sigtest-9.1.txt
@@ -0,0 +1,734 @@
+#Signature file v4.1
+#Version 9.1
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitPermittedSubclass(java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubclasses,permittedSubclasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-9.2.txt b/asm/src/test/resources/sigtest-9.2.txt
new file mode 100644
index 00000000..23ca2d0c
--- /dev/null
+++ b/asm/src/test/resources/sigtest-9.2.txt
@@ -0,0 +1,735 @@
+#Signature file v4.1
+#Version 9.2
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,MAX_BUFFER_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitPermittedSubclass(java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubclasses,permittedSubclasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons public init(int)
+cons public init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+hfds delegate
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons public init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/asm/src/test/resources/sigtest-9.4.txt b/asm/src/test/resources/sigtest-9.4.txt
new file mode 100644
index 00000000..12624ac4
--- /dev/null
+++ b/asm/src/test/resources/sigtest-9.4.txt
@@ -0,0 +1,745 @@
+#Signature file v4.1
+#Version 9.4
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.IndexOutOfBoundsException
+cons public init()
+cons public init(java.lang.String)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract org.objectweb.asm.AnnotationVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.AnnotationVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.AnnotationVisitor av
+meth public org.objectweb.asm.AnnotationVisitor getDelegate()
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,java.lang.String)
+meth public org.objectweb.asm.AnnotationVisitor visitArray(java.lang.String)
+meth public void visit(java.lang.String,java.lang.Object)
+meth public void visitEnd()
+meth public void visitEnum(java.lang.String,java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.Attribute
+cons protected init(java.lang.String)
+fld public final java.lang.String type
+meth protected org.objectweb.asm.Attribute read(org.objectweb.asm.ClassReader,int,int,char[],int,org.objectweb.asm.Label[])
+meth protected org.objectweb.asm.ByteVector write(org.objectweb.asm.ClassWriter,byte[],int,int,int)
+meth protected org.objectweb.asm.Label[] getLabels()
+meth public boolean isCodeAttribute()
+meth public boolean isUnknown()
+supr java.lang.Object
+hfds content,nextAttribute
+hcls Set
+
+CLSS public org.objectweb.asm.ByteVector
+cons public init()
+cons public init(int)
+meth public int size()
+meth public org.objectweb.asm.ByteVector putByte(int)
+meth public org.objectweb.asm.ByteVector putByteArray(byte[],int,int)
+meth public org.objectweb.asm.ByteVector putInt(int)
+meth public org.objectweb.asm.ByteVector putLong(long)
+meth public org.objectweb.asm.ByteVector putShort(int)
+meth public org.objectweb.asm.ByteVector putUTF8(java.lang.String)
+supr java.lang.Object
+hfds data,length
+
+CLSS public org.objectweb.asm.ClassReader
+cons public init(byte[])
+cons public init(byte[],int,int)
+cons public init(java.io.InputStream) throws java.io.IOException
+cons public init(java.lang.String) throws java.io.IOException
+fld public final byte[] b
+fld public final int header
+fld public final static int EXPAND_FRAMES = 8
+fld public final static int SKIP_CODE = 1
+fld public final static int SKIP_DEBUG = 2
+fld public final static int SKIP_FRAMES = 4
+meth protected org.objectweb.asm.Label readLabel(int,org.objectweb.asm.Label[])
+meth public int getAccess()
+meth public int getItem(int)
+meth public int getItemCount()
+meth public int getMaxStringLength()
+meth public int readByte(int)
+meth public int readInt(int)
+meth public int readUnsignedShort(int)
+meth public java.lang.Object readConst(int,char[])
+meth public java.lang.String getClassName()
+meth public java.lang.String getSuperName()
+meth public java.lang.String readClass(int,char[])
+meth public java.lang.String readModule(int,char[])
+meth public java.lang.String readPackage(int,char[])
+meth public java.lang.String readUTF8(int,char[])
+meth public java.lang.String[] getInterfaces()
+meth public long readLong(int)
+meth public short readShort(int)
+meth public void accept(org.objectweb.asm.ClassVisitor,int)
+meth public void accept(org.objectweb.asm.ClassVisitor,org.objectweb.asm.Attribute[],int)
+supr java.lang.Object
+hfds EXPAND_ASM_INSNS,INPUT_STREAM_DATA_CHUNK_SIZE,MAX_BUFFER_SIZE,bootstrapMethodOffsets,classFileBuffer,constantDynamicValues,constantUtf8Values,cpInfoOffsets,maxStringLength
+
+CLSS public final org.objectweb.asm.ClassTooLargeException
+cons public init(java.lang.String,int)
+meth public int getConstantPoolCount()
+meth public java.lang.String getClassName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,constantPoolCount,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.ClassVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ClassVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ClassVisitor cv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.ClassVisitor getDelegate()
+meth public org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+meth public void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public void visitNestHost(java.lang.String)
+meth public void visitNestMember(java.lang.String)
+meth public void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public void visitPermittedSubclass(java.lang.String)
+meth public void visitSource(java.lang.String,java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.ClassWriter
+cons public init(int)
+cons public init(org.objectweb.asm.ClassReader,int)
+fld public final static int COMPUTE_FRAMES = 2
+fld public final static int COMPUTE_MAXS = 1
+meth protected java.lang.ClassLoader getClassLoader()
+meth protected java.lang.String getCommonSuperClass(java.lang.String,java.lang.String)
+meth public !varargs int newConstantDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs int newInvokeDynamic(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean hasFlags(int)
+meth public byte[] toByteArray()
+meth public final org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public final org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public final org.objectweb.asm.FieldVisitor visitField(int,java.lang.String,java.lang.String,java.lang.String,java.lang.Object)
+meth public final org.objectweb.asm.MethodVisitor visitMethod(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final org.objectweb.asm.ModuleVisitor visitModule(java.lang.String,int,java.lang.String)
+meth public final org.objectweb.asm.RecordComponentVisitor visitRecordComponent(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visit(int,int,java.lang.String,java.lang.String,java.lang.String,java.lang.String[])
+meth public final void visitAttribute(org.objectweb.asm.Attribute)
+meth public final void visitEnd()
+meth public final void visitInnerClass(java.lang.String,java.lang.String,java.lang.String,int)
+meth public final void visitNestHost(java.lang.String)
+meth public final void visitNestMember(java.lang.String)
+meth public final void visitOuterClass(java.lang.String,java.lang.String,java.lang.String)
+meth public final void visitPermittedSubclass(java.lang.String)
+meth public final void visitSource(java.lang.String,java.lang.String)
+meth public int newClass(java.lang.String)
+meth public int newConst(java.lang.Object)
+meth public int newField(java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String)
+meth public int newHandle(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethod(java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public int newMethodType(java.lang.String)
+meth public int newModule(java.lang.String)
+meth public int newNameType(java.lang.String,java.lang.String)
+meth public int newPackage(java.lang.String)
+meth public int newUTF8(java.lang.String)
+supr org.objectweb.asm.ClassVisitor
+hfds accessFlags,compute,debugExtension,enclosingClassIndex,enclosingMethodIndex,firstAttribute,firstField,firstMethod,firstRecordComponent,flags,innerClasses,interfaceCount,interfaces,lastField,lastMethod,lastRecordComponent,lastRuntimeInvisibleAnnotation,lastRuntimeInvisibleTypeAnnotation,lastRuntimeVisibleAnnotation,lastRuntimeVisibleTypeAnnotation,moduleWriter,nestHostClassIndex,nestMemberClasses,numberOfInnerClasses,numberOfNestMemberClasses,numberOfPermittedSubclasses,permittedSubclasses,signatureIndex,sourceFileIndex,superClass,symbolTable,thisClass,version
+
+CLSS public final org.objectweb.asm.ConstantDynamic
+cons public !varargs init(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int getBootstrapMethodArgumentCount()
+meth public int getSize()
+meth public int hashCode()
+meth public java.lang.Object getBootstrapMethodArgument(int)
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Handle getBootstrapMethod()
+supr java.lang.Object
+hfds bootstrapMethod,bootstrapMethodArguments,descriptor,name
+
+CLSS public abstract org.objectweb.asm.FieldVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.FieldVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.FieldVisitor fv
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.FieldVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Handle
+cons public init(int,java.lang.String,java.lang.String,java.lang.String)
+cons public init(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public boolean equals(java.lang.Object)
+meth public boolean isInterface()
+meth public int getTag()
+meth public int hashCode()
+meth public java.lang.String getDesc()
+meth public java.lang.String getName()
+meth public java.lang.String getOwner()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds descriptor,isInterface,name,owner,tag
+
+CLSS public org.objectweb.asm.Label
+cons public init()
+fld public java.lang.Object info
+meth public int getOffset()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds EMPTY_LIST,FLAG_DEBUG_ONLY,FLAG_JUMP_TARGET,FLAG_REACHABLE,FLAG_RESOLVED,FLAG_SUBROUTINE_CALLER,FLAG_SUBROUTINE_END,FLAG_SUBROUTINE_START,FORWARD_REFERENCES_CAPACITY_INCREMENT,FORWARD_REFERENCE_HANDLE_MASK,FORWARD_REFERENCE_TYPE_MASK,FORWARD_REFERENCE_TYPE_SHORT,FORWARD_REFERENCE_TYPE_WIDE,LINE_NUMBERS_CAPACITY_INCREMENT,bytecodeOffset,flags,forwardReferences,frame,inputStackSize,lineNumber,nextBasicBlock,nextListElement,otherLineNumbers,outgoingEdges,outputStackMax,outputStackSize,subroutineId
+
+CLSS public final org.objectweb.asm.MethodTooLargeException
+cons public init(java.lang.String,java.lang.String,java.lang.String,int)
+meth public int getCodeSize()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getMethodName()
+supr java.lang.IndexOutOfBoundsException
+hfds className,codeSize,descriptor,methodName,serialVersionUID
+
+CLSS public abstract org.objectweb.asm.MethodVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.MethodVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.MethodVisitor mv
+meth public !varargs void visitInvokeDynamicInsn(java.lang.String,java.lang.String,org.objectweb.asm.Handle,java.lang.Object[])
+meth public !varargs void visitTableSwitchInsn(int,int,org.objectweb.asm.Label,org.objectweb.asm.Label[])
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotationDefault()
+meth public org.objectweb.asm.AnnotationVisitor visitInsnAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitLocalVariableAnnotation(int,org.objectweb.asm.TypePath,org.objectweb.asm.Label[],org.objectweb.asm.Label[],int[],java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTryCatchAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.MethodVisitor getDelegate()
+meth public void visitAnnotableParameterCount(int,boolean)
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitCode()
+meth public void visitEnd()
+meth public void visitFieldInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitFrame(int,int,java.lang.Object[],int,java.lang.Object[])
+meth public void visitIincInsn(int,int)
+meth public void visitInsn(int)
+meth public void visitIntInsn(int,int)
+meth public void visitJumpInsn(int,org.objectweb.asm.Label)
+meth public void visitLabel(org.objectweb.asm.Label)
+meth public void visitLdcInsn(java.lang.Object)
+meth public void visitLineNumber(int,org.objectweb.asm.Label)
+meth public void visitLocalVariable(java.lang.String,java.lang.String,java.lang.String,org.objectweb.asm.Label,org.objectweb.asm.Label,int)
+meth public void visitLookupSwitchInsn(org.objectweb.asm.Label,int[],org.objectweb.asm.Label[])
+meth public void visitMaxs(int,int)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String)
+meth public void visitMethodInsn(int,java.lang.String,java.lang.String,java.lang.String,boolean)
+meth public void visitMultiANewArrayInsn(java.lang.String,int)
+meth public void visitParameter(java.lang.String,int)
+meth public void visitTryCatchBlock(org.objectweb.asm.Label,org.objectweb.asm.Label,org.objectweb.asm.Label,java.lang.String)
+meth public void visitTypeInsn(int,java.lang.String)
+meth public void visitVarInsn(int,int)
+supr java.lang.Object
+hfds REQUIRES_ASM5
+
+CLSS public abstract org.objectweb.asm.ModuleVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.ModuleVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.ModuleVisitor mv
+meth public !varargs void visitExport(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitOpen(java.lang.String,int,java.lang.String[])
+meth public !varargs void visitProvide(java.lang.String,java.lang.String[])
+meth public org.objectweb.asm.ModuleVisitor getDelegate()
+meth public void visitEnd()
+meth public void visitMainClass(java.lang.String)
+meth public void visitPackage(java.lang.String)
+meth public void visitRequire(java.lang.String,int,java.lang.String)
+meth public void visitUse(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface org.objectweb.asm.Opcodes
+fld public final static int AALOAD = 50
+fld public final static int AASTORE = 83
+fld public final static int ACC_ABSTRACT = 1024
+fld public final static int ACC_ANNOTATION = 8192
+fld public final static int ACC_BRIDGE = 64
+fld public final static int ACC_DEPRECATED = 131072
+fld public final static int ACC_ENUM = 16384
+fld public final static int ACC_FINAL = 16
+fld public final static int ACC_INTERFACE = 512
+fld public final static int ACC_MANDATED = 32768
+fld public final static int ACC_MODULE = 32768
+fld public final static int ACC_NATIVE = 256
+fld public final static int ACC_OPEN = 32
+fld public final static int ACC_PRIVATE = 2
+fld public final static int ACC_PROTECTED = 4
+fld public final static int ACC_PUBLIC = 1
+fld public final static int ACC_RECORD = 65536
+fld public final static int ACC_STATIC = 8
+fld public final static int ACC_STATIC_PHASE = 64
+fld public final static int ACC_STRICT = 2048
+fld public final static int ACC_SUPER = 32
+fld public final static int ACC_SYNCHRONIZED = 32
+fld public final static int ACC_SYNTHETIC = 4096
+fld public final static int ACC_TRANSIENT = 128
+fld public final static int ACC_TRANSITIVE = 32
+fld public final static int ACC_VARARGS = 128
+fld public final static int ACC_VOLATILE = 64
+fld public final static int ACONST_NULL = 1
+fld public final static int ALOAD = 25
+fld public final static int ANEWARRAY = 189
+fld public final static int ARETURN = 176
+fld public final static int ARRAYLENGTH = 190
+fld public final static int ASM10_EXPERIMENTAL = 17432576
+fld public final static int ASM4 = 262144
+fld public final static int ASM5 = 327680
+fld public final static int ASM6 = 393216
+fld public final static int ASM7 = 458752
+fld public final static int ASM8 = 524288
+fld public final static int ASM9 = 589824
+fld public final static int ASTORE = 58
+fld public final static int ATHROW = 191
+fld public final static int BALOAD = 51
+fld public final static int BASTORE = 84
+fld public final static int BIPUSH = 16
+fld public final static int CALOAD = 52
+fld public final static int CASTORE = 85
+fld public final static int CHECKCAST = 192
+fld public final static int D2F = 144
+fld public final static int D2I = 142
+fld public final static int D2L = 143
+fld public final static int DADD = 99
+fld public final static int DALOAD = 49
+fld public final static int DASTORE = 82
+fld public final static int DCMPG = 152
+fld public final static int DCMPL = 151
+fld public final static int DCONST_0 = 14
+fld public final static int DCONST_1 = 15
+fld public final static int DDIV = 111
+fld public final static int DLOAD = 24
+fld public final static int DMUL = 107
+fld public final static int DNEG = 119
+fld public final static int DREM = 115
+fld public final static int DRETURN = 175
+fld public final static int DSTORE = 57
+fld public final static int DSUB = 103
+fld public final static int DUP = 89
+fld public final static int DUP2 = 92
+fld public final static int DUP2_X1 = 93
+fld public final static int DUP2_X2 = 94
+fld public final static int DUP_X1 = 90
+fld public final static int DUP_X2 = 91
+fld public final static int F2D = 141
+fld public final static int F2I = 139
+fld public final static int F2L = 140
+fld public final static int FADD = 98
+fld public final static int FALOAD = 48
+fld public final static int FASTORE = 81
+fld public final static int FCMPG = 150
+fld public final static int FCMPL = 149
+fld public final static int FCONST_0 = 11
+fld public final static int FCONST_1 = 12
+fld public final static int FCONST_2 = 13
+fld public final static int FDIV = 110
+fld public final static int FLOAD = 23
+fld public final static int FMUL = 106
+fld public final static int FNEG = 118
+fld public final static int FREM = 114
+fld public final static int FRETURN = 174
+fld public final static int FSTORE = 56
+fld public final static int FSUB = 102
+fld public final static int F_APPEND = 1
+fld public final static int F_CHOP = 2
+fld public final static int F_FULL = 0
+fld public final static int F_NEW = -1
+fld public final static int F_SAME = 3
+fld public final static int F_SAME1 = 4
+fld public final static int GETFIELD = 180
+fld public final static int GETSTATIC = 178
+fld public final static int GOTO = 167
+fld public final static int H_GETFIELD = 1
+fld public final static int H_GETSTATIC = 2
+fld public final static int H_INVOKEINTERFACE = 9
+fld public final static int H_INVOKESPECIAL = 7
+fld public final static int H_INVOKESTATIC = 6
+fld public final static int H_INVOKEVIRTUAL = 5
+fld public final static int H_NEWINVOKESPECIAL = 8
+fld public final static int H_PUTFIELD = 3
+fld public final static int H_PUTSTATIC = 4
+fld public final static int I2B = 145
+fld public final static int I2C = 146
+fld public final static int I2D = 135
+fld public final static int I2F = 134
+fld public final static int I2L = 133
+fld public final static int I2S = 147
+fld public final static int IADD = 96
+fld public final static int IALOAD = 46
+fld public final static int IAND = 126
+fld public final static int IASTORE = 79
+fld public final static int ICONST_0 = 3
+fld public final static int ICONST_1 = 4
+fld public final static int ICONST_2 = 5
+fld public final static int ICONST_3 = 6
+fld public final static int ICONST_4 = 7
+fld public final static int ICONST_5 = 8
+fld public final static int ICONST_M1 = 2
+fld public final static int IDIV = 108
+fld public final static int IFEQ = 153
+fld public final static int IFGE = 156
+fld public final static int IFGT = 157
+fld public final static int IFLE = 158
+fld public final static int IFLT = 155
+fld public final static int IFNE = 154
+fld public final static int IFNONNULL = 199
+fld public final static int IFNULL = 198
+fld public final static int IF_ACMPEQ = 165
+fld public final static int IF_ACMPNE = 166
+fld public final static int IF_ICMPEQ = 159
+fld public final static int IF_ICMPGE = 162
+fld public final static int IF_ICMPGT = 163
+fld public final static int IF_ICMPLE = 164
+fld public final static int IF_ICMPLT = 161
+fld public final static int IF_ICMPNE = 160
+fld public final static int IINC = 132
+fld public final static int ILOAD = 21
+fld public final static int IMUL = 104
+fld public final static int INEG = 116
+fld public final static int INSTANCEOF = 193
+fld public final static int INVOKEDYNAMIC = 186
+fld public final static int INVOKEINTERFACE = 185
+fld public final static int INVOKESPECIAL = 183
+fld public final static int INVOKESTATIC = 184
+fld public final static int INVOKEVIRTUAL = 182
+fld public final static int IOR = 128
+fld public final static int IREM = 112
+fld public final static int IRETURN = 172
+fld public final static int ISHL = 120
+fld public final static int ISHR = 122
+fld public final static int ISTORE = 54
+fld public final static int ISUB = 100
+fld public final static int IUSHR = 124
+fld public final static int IXOR = 130
+fld public final static int JSR = 168
+fld public final static int L2D = 138
+fld public final static int L2F = 137
+fld public final static int L2I = 136
+fld public final static int LADD = 97
+fld public final static int LALOAD = 47
+fld public final static int LAND = 127
+fld public final static int LASTORE = 80
+fld public final static int LCMP = 148
+fld public final static int LCONST_0 = 9
+fld public final static int LCONST_1 = 10
+fld public final static int LDC = 18
+fld public final static int LDIV = 109
+fld public final static int LLOAD = 22
+fld public final static int LMUL = 105
+fld public final static int LNEG = 117
+fld public final static int LOOKUPSWITCH = 171
+fld public final static int LOR = 129
+fld public final static int LREM = 113
+fld public final static int LRETURN = 173
+fld public final static int LSHL = 121
+fld public final static int LSHR = 123
+fld public final static int LSTORE = 55
+fld public final static int LSUB = 101
+fld public final static int LUSHR = 125
+fld public final static int LXOR = 131
+fld public final static int MONITORENTER = 194
+fld public final static int MONITOREXIT = 195
+fld public final static int MULTIANEWARRAY = 197
+fld public final static int NEW = 187
+fld public final static int NEWARRAY = 188
+fld public final static int NOP = 0
+fld public final static int POP = 87
+fld public final static int POP2 = 88
+fld public final static int PUTFIELD = 181
+fld public final static int PUTSTATIC = 179
+fld public final static int RET = 169
+fld public final static int RETURN = 177
+fld public final static int SALOAD = 53
+fld public final static int SASTORE = 86
+fld public final static int SIPUSH = 17
+fld public final static int SOURCE_DEPRECATED = 256
+fld public final static int SOURCE_MASK = 256
+fld public final static int SWAP = 95
+fld public final static int TABLESWITCH = 170
+fld public final static int T_BOOLEAN = 4
+fld public final static int T_BYTE = 8
+fld public final static int T_CHAR = 5
+fld public final static int T_DOUBLE = 7
+fld public final static int T_FLOAT = 6
+fld public final static int T_INT = 10
+fld public final static int T_LONG = 11
+fld public final static int T_SHORT = 9
+fld public final static int V10 = 54
+fld public final static int V11 = 55
+fld public final static int V12 = 56
+fld public final static int V13 = 57
+fld public final static int V14 = 58
+fld public final static int V15 = 59
+fld public final static int V16 = 60
+fld public final static int V17 = 61
+fld public final static int V18 = 62
+fld public final static int V19 = 63
+fld public final static int V1_1 = 196653
+fld public final static int V1_2 = 46
+fld public final static int V1_3 = 47
+fld public final static int V1_4 = 48
+fld public final static int V1_5 = 49
+fld public final static int V1_6 = 50
+fld public final static int V1_7 = 51
+fld public final static int V1_8 = 52
+fld public final static int V20 = 64
+fld public final static int V9 = 53
+fld public final static int V_PREVIEW = -65536
+fld public final static java.lang.Integer DOUBLE
+fld public final static java.lang.Integer FLOAT
+fld public final static java.lang.Integer INTEGER
+fld public final static java.lang.Integer LONG
+fld public final static java.lang.Integer NULL
+fld public final static java.lang.Integer TOP
+fld public final static java.lang.Integer UNINITIALIZED_THIS
+
+CLSS public abstract org.objectweb.asm.RecordComponentVisitor
+cons protected init(int)
+cons protected init(int,org.objectweb.asm.RecordComponentVisitor)
+fld protected final int api
+fld protected org.objectweb.asm.RecordComponentVisitor delegate
+meth public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String,boolean)
+meth public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int,org.objectweb.asm.TypePath,java.lang.String,boolean)
+meth public org.objectweb.asm.RecordComponentVisitor getDelegate()
+meth public void visitAttribute(org.objectweb.asm.Attribute)
+meth public void visitEnd()
+supr java.lang.Object
+
+CLSS public final org.objectweb.asm.Type
+fld public final static int ARRAY = 9
+fld public final static int BOOLEAN = 1
+fld public final static int BYTE = 3
+fld public final static int CHAR = 2
+fld public final static int DOUBLE = 8
+fld public final static int FLOAT = 6
+fld public final static int INT = 5
+fld public final static int LONG = 7
+fld public final static int METHOD = 11
+fld public final static int OBJECT = 10
+fld public final static int SHORT = 4
+fld public final static int VOID = 0
+fld public final static org.objectweb.asm.Type BOOLEAN_TYPE
+fld public final static org.objectweb.asm.Type BYTE_TYPE
+fld public final static org.objectweb.asm.Type CHAR_TYPE
+fld public final static org.objectweb.asm.Type DOUBLE_TYPE
+fld public final static org.objectweb.asm.Type FLOAT_TYPE
+fld public final static org.objectweb.asm.Type INT_TYPE
+fld public final static org.objectweb.asm.Type LONG_TYPE
+fld public final static org.objectweb.asm.Type SHORT_TYPE
+fld public final static org.objectweb.asm.Type VOID_TYPE
+meth public !varargs static java.lang.String getMethodDescriptor(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public !varargs static org.objectweb.asm.Type getMethodType(org.objectweb.asm.Type,org.objectweb.asm.Type[])
+meth public boolean equals(java.lang.Object)
+meth public int getArgumentsAndReturnSizes()
+meth public int getDimensions()
+meth public int getOpcode(int)
+meth public int getSize()
+meth public int getSort()
+meth public int hashCode()
+meth public java.lang.String getClassName()
+meth public java.lang.String getDescriptor()
+meth public java.lang.String getInternalName()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.Type getElementType()
+meth public org.objectweb.asm.Type getReturnType()
+meth public org.objectweb.asm.Type[] getArgumentTypes()
+meth public static int getArgumentsAndReturnSizes(java.lang.String)
+meth public static java.lang.String getConstructorDescriptor(java.lang.reflect.Constructor<?>)
+meth public static java.lang.String getDescriptor(java.lang.Class<?>)
+meth public static java.lang.String getInternalName(java.lang.Class<?>)
+meth public static java.lang.String getMethodDescriptor(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getMethodType(java.lang.String)
+meth public static org.objectweb.asm.Type getObjectType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.String)
+meth public static org.objectweb.asm.Type getReturnType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type getType(java.lang.Class<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.String)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Constructor<?>)
+meth public static org.objectweb.asm.Type getType(java.lang.reflect.Method)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.String)
+meth public static org.objectweb.asm.Type[] getArgumentTypes(java.lang.reflect.Method)
+supr java.lang.Object
+hfds INTERNAL,PRIMITIVE_DESCRIPTORS,sort,valueBegin,valueBuffer,valueEnd
+
+CLSS public final org.objectweb.asm.TypePath
+fld public final static int ARRAY_ELEMENT = 0
+fld public final static int INNER_TYPE = 1
+fld public final static int TYPE_ARGUMENT = 3
+fld public final static int WILDCARD_BOUND = 2
+meth public int getLength()
+meth public int getStep(int)
+meth public int getStepArgument(int)
+meth public java.lang.String toString()
+meth public static org.objectweb.asm.TypePath fromString(java.lang.String)
+supr java.lang.Object
+hfds typePathContainer,typePathOffset
+
+CLSS public org.objectweb.asm.TypeReference
+cons public init(int)
+fld public final static int CAST = 71
+fld public final static int CLASS_EXTENDS = 16
+fld public final static int CLASS_TYPE_PARAMETER = 0
+fld public final static int CLASS_TYPE_PARAMETER_BOUND = 17
+fld public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 72
+fld public final static int CONSTRUCTOR_REFERENCE = 69
+fld public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 74
+fld public final static int EXCEPTION_PARAMETER = 66
+fld public final static int FIELD = 19
+fld public final static int INSTANCEOF = 67
+fld public final static int LOCAL_VARIABLE = 64
+fld public final static int METHOD_FORMAL_PARAMETER = 22
+fld public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 73
+fld public final static int METHOD_RECEIVER = 21
+fld public final static int METHOD_REFERENCE = 70
+fld public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 75
+fld public final static int METHOD_RETURN = 20
+fld public final static int METHOD_TYPE_PARAMETER = 1
+fld public final static int METHOD_TYPE_PARAMETER_BOUND = 18
+fld public final static int NEW = 68
+fld public final static int RESOURCE_VARIABLE = 65
+fld public final static int THROWS = 23
+meth public int getExceptionIndex()
+meth public int getFormalParameterIndex()
+meth public int getSort()
+meth public int getSuperTypeIndex()
+meth public int getTryCatchBlockIndex()
+meth public int getTypeArgumentIndex()
+meth public int getTypeParameterBoundIndex()
+meth public int getTypeParameterIndex()
+meth public int getValue()
+meth public static org.objectweb.asm.TypeReference newExceptionReference(int)
+meth public static org.objectweb.asm.TypeReference newFormalParameterReference(int)
+meth public static org.objectweb.asm.TypeReference newSuperTypeReference(int)
+meth public static org.objectweb.asm.TypeReference newTryCatchReference(int)
+meth public static org.objectweb.asm.TypeReference newTypeArgumentReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterBoundReference(int,int,int)
+meth public static org.objectweb.asm.TypeReference newTypeParameterReference(int,int)
+meth public static org.objectweb.asm.TypeReference newTypeReference(int)
+supr java.lang.Object
+hfds targetTypeAndInfo
+
+CLSS public org.objectweb.asm.signature.SignatureReader
+cons public init(java.lang.String)
+meth public void accept(org.objectweb.asm.signature.SignatureVisitor)
+meth public void acceptType(org.objectweb.asm.signature.SignatureVisitor)
+supr java.lang.Object
+hfds signatureValue
+
+CLSS public abstract org.objectweb.asm.signature.SignatureVisitor
+cons protected init(int)
+fld protected final int api
+fld public final static char EXTENDS = '+'
+fld public final static char INSTANCEOF = '='
+fld public final static char SUPER = '-'
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr java.lang.Object
+
+CLSS public org.objectweb.asm.signature.SignatureWriter
+cons public init()
+meth public java.lang.String toString()
+meth public org.objectweb.asm.signature.SignatureVisitor visitArrayType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitClassBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitExceptionType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterface()
+meth public org.objectweb.asm.signature.SignatureVisitor visitInterfaceBound()
+meth public org.objectweb.asm.signature.SignatureVisitor visitParameterType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitReturnType()
+meth public org.objectweb.asm.signature.SignatureVisitor visitSuperclass()
+meth public org.objectweb.asm.signature.SignatureVisitor visitTypeArgument(char)
+meth public void visitBaseType(char)
+meth public void visitClassType(java.lang.String)
+meth public void visitEnd()
+meth public void visitFormalTypeParameter(java.lang.String)
+meth public void visitInnerClassType(java.lang.String)
+meth public void visitTypeArgument()
+meth public void visitTypeVariable(java.lang.String)
+supr org.objectweb.asm.signature.SignatureVisitor
+hfds argumentStack,hasFormals,hasParameters,stringBuilder
+
diff --git a/benchmarks/libs/csg-bytecode-1.0.0.jar b/benchmarks/libs/csg-bytecode-1.0.0.jar
new file mode 100644
index 00000000..99cba8de
--- /dev/null
+++ b/benchmarks/libs/csg-bytecode-1.0.0.jar
Binary files differ
diff --git a/benchmarks/libs/jclasslib.jar b/benchmarks/libs/jclasslib.jar
new file mode 100644
index 00000000..acd5ee09
--- /dev/null
+++ b/benchmarks/libs/jclasslib.jar
Binary files differ
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java
new file mode 100644
index 00000000..079383df
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AbstractBenchmark.java
@@ -0,0 +1,216 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.util.ArrayList;
+
+/**
+ * A benchmark to benchmark different versions of ASM and possibly other bytecode libraries.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AbstractBenchmark {
+
+ // The root directory of the ASM project.
+ private static final String ROOT_DIR = System.getProperty("user.dir");
+
+ // The sub directories of ROOT_DIR where the different versions of ASM can be found.
+ private static final String BUILD_DIR = "/benchmarks/build/";
+ private static final String ASM4_0 = BUILD_DIR + "asm4.0/";
+ private static final String ASM5_0 = BUILD_DIR + "asm5.0.1/";
+ private static final String ASM6_0 = BUILD_DIR + "asm6.0/";
+ private static final String ASM7_0 = BUILD_DIR + "asm7.0/";
+ private static final String ASM8_0 = BUILD_DIR + "asm8.0.1/";
+ private static final String ASM9_0 = BUILD_DIR + "asm9.0/";
+
+ // The directories where the Java 1.5 input data classes for the benchmarks can be found.
+ private static final String ASM_CORE_CURRENT = "/asm/build/classes/java/main/";
+ private static final String ASM_TREE_CURRENT = "/asm-tree/build/classes/java/main/";
+
+ // The directory where the Java 8 input data classes for the benchmarks can be found.
+ private static final String INPUT_CLASSES_JAVA8 =
+ "/benchmarks/build/input-classes-java8/io/vavr/control/";
+
+ private final String asmBenchmarkClass;
+
+ /**
+ * Some Java 1.5 class files that can be used as input data for benchmarks. These classes do not
+ * have stack map frames, invokedynamic, etc, and thus cannot be used to benchmark ASM performance
+ * for these features. However, they can be used to compare ASM with other libraries that don't
+ * support these class file features (including ASM itself, before ASM 5.0).
+ */
+ ArrayList<byte[]> classFiles;
+
+ /**
+ * Some Java 8 class files that can be used as input data for ASM benchmarks. These classes
+ * contain stack map frames and invokedynamic instructions.
+ */
+ ArrayList<byte[]> java8classFiles;
+
+ /** The ASM versions that can be benchmarked. */
+ public enum AsmVersion {
+ V4_0,
+ V5_0,
+ V6_0,
+ V7_0,
+ V8_0,
+ V9_0,
+ V_CURRENT;
+
+ URL[] getUrls(final String baseUrl) throws MalformedURLException {
+ switch (this) {
+ case V4_0:
+ return new URL[] {new URL(baseUrl + ASM4_0)};
+ case V5_0:
+ return new URL[] {new URL(baseUrl + ASM5_0)};
+ case V6_0:
+ return new URL[] {new URL(baseUrl + ASM6_0)};
+ case V7_0:
+ return new URL[] {new URL(baseUrl + ASM7_0)};
+ case V8_0:
+ return new URL[] {new URL(baseUrl + ASM8_0)};
+ case V9_0:
+ return new URL[] {new URL(baseUrl + ASM9_0)};
+ case V_CURRENT:
+ return new URL[] {
+ new URL(baseUrl + ASM_CORE_CURRENT), new URL(baseUrl + ASM_TREE_CURRENT)
+ };
+ default:
+ throw new AssertionError();
+ }
+ }
+ }
+
+ /**
+ * Constructs a new {@link AbstractBenchmark}.
+ *
+ * @param asmBenchmarkClass the benchmark class to instantiate for the ASM benchmarks.
+ */
+ protected AbstractBenchmark(final String asmBenchmarkClass) {
+ this.asmBenchmarkClass = asmBenchmarkClass;
+ }
+
+ /** Creates and populates {@link #classFiles} with some class files read from disk. */
+ protected void prepareClasses() throws IOException {
+ classFiles = new ArrayList<>();
+ java8classFiles = new ArrayList<>();
+ findClasses(new File(ROOT_DIR + ASM_CORE_CURRENT), classFiles);
+ findClasses(new File(ROOT_DIR + ASM_TREE_CURRENT), classFiles);
+ findClasses(new File(ROOT_DIR + INPUT_CLASSES_JAVA8), java8classFiles);
+ }
+
+ private static void findClasses(final File directory, final ArrayList<byte[]> classFiles)
+ throws IOException {
+ for (File file : directory.listFiles()) {
+ if (file.isDirectory()) {
+ findClasses(file, classFiles);
+ } else if (file.getName().endsWith(".class")) {
+ classFiles.add(readInputStream(Files.newInputStream(file.toPath())));
+ }
+ }
+ }
+
+ private static byte[] readInputStream(final InputStream inputStream) throws IOException {
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ byte[] data = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
+ outputStream.write(data, 0, bytesRead);
+ }
+ outputStream.flush();
+ return outputStream.toByteArray();
+ }
+ }
+
+ /** A factory of ASM benchmark objects, using a specific version of the ASM library. */
+ class AsmBenchmarkFactory extends URLClassLoader {
+
+ /**
+ * Constructs an {@link AsmBenchmarkFactory}.
+ *
+ * @param asmVersion the ASM version to use.
+ * @throws MalformedURLException if the ROOT_DIR path is malformed.
+ */
+ AsmBenchmarkFactory(final AsmVersion asmVersion) throws MalformedURLException {
+ super(asmVersion.getUrls("file://" + ROOT_DIR));
+ }
+
+ /**
+ * Returns a new instance of the class specified in the benchmark's constructor.
+ *
+ * @return a new instance of the class specified in the benchmark's constructor.
+ * @throws ClassNotFoundException if the class can't be found.
+ * @throws ReflectiveOperationException if the class can't be instantiated.
+ */
+ public Object newAsmBenchmark() throws ClassNotFoundException, ReflectiveOperationException {
+ return loadClass(asmBenchmarkClass).newInstance();
+ }
+
+ @Override
+ protected Class<?> loadClass(final String name, final boolean resolve)
+ throws ClassNotFoundException {
+ // Force the loading of the asmBenchmarkClass class by this class loader (and not its parent).
+ // This is needed to make sure that the classes it references (i.e. the ASM library classes)
+ // will be loaded by this class loader too.
+ if (name.startsWith(asmBenchmarkClass)) {
+ byte[] classFile;
+ try {
+ classFile = readInputStream(getResourceAsStream(name.replace('.', '/') + ".class"));
+ } catch (IOException e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ Class<?> c = defineClass(name, classFile, 0, classFile.length);
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ // Look for the specified class *first* in asmDirectories, *then* using the parent class
+ // loader. This is the reverse of the default lookup order, and is necessary to make sure we
+ // load the correct version of ASM (the parent class loader may have an ASM version in its
+ // class path, because some components of the JMH framework depend on ASM).
+ try {
+ Class<?> c = findClass(name);
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ } catch (ClassNotFoundException e) {
+ return super.loadClass(name, resolve);
+ }
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Adapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Adapter.java
new file mode 100644
index 00000000..6b72491c
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Adapter.java
@@ -0,0 +1,147 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+/**
+ * An empty class adapter, which reads and writes Java classes with no intermediate transformation.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class Adapter {
+
+ /**
+ * Returns the version of this class adapter.
+ *
+ * @return the version of this class adapter, or an empty string if there is no version.
+ */
+ public String getVersion() {
+ return "";
+ }
+
+ /**
+ * Returns the access flags, name, super class and interfaces of the given class.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return the access flags, name, super class and interfaces of the given class.
+ */
+ public ClassInfo getClassInfo(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns an in-memory, object representation of the given class.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return an in-memory, object representation of the given class.
+ */
+ public Object getClassObjectModel(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Reads a class and returns the number of 'elements' it contains.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return the number of 'elements' found in the given class.
+ */
+ public int read(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Reads a class and writes and returns an equivalent one.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @param computeMaxs whether to recompute the maximum stack size and maximum number of local
+ * variables for each method.
+ * @return the rebuilt class.
+ */
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMaxs) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Reads a class and writes and returns an equivalent one with all its stack map frames
+ * recomputed.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return the rebuilt class.
+ */
+ public byte[] readAndWriteWithComputeFrames(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Reads a class and writes and returns an equivalent one, sharing the same constant pool.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return the rebuilt class.
+ */
+ public byte[] readAndWriteWithCopyPool(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Reads a class and writes and returns an equivalent one, via the construction of in-memory,
+ * object representation of the class.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return the rebuilt class.
+ */
+ public byte[] readAndWriteWithObjectModel(final byte[] classFile) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** The access flags, name, super class and interfaces of a class. */
+ public static class ClassInfo {
+
+ int access;
+ String name;
+ String superClass;
+ String[] interfaces;
+
+ /**
+ * Constructs a new {@link ClassInfo}.
+ *
+ * @param access the class's access flags.
+ * @param name the internal name of the class.
+ * @param superClass the internal of name of the super class.
+ * @param interfaces the internal names of the class's interfaces
+ */
+ public ClassInfo(
+ final int access,
+ final String name,
+ final String superClass,
+ final String[] interfaces) { // NOPMD(ArrayIsStoredDirectly): non public API.
+ this.access = access;
+ this.name = name;
+ this.superClass = superClass;
+ this.interfaces = interfaces;
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmark.java
new file mode 100644
index 00000000..5fbaba34
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmark.java
@@ -0,0 +1,542 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * A benchmark to measure the performance of several Java bytecode libraries when reading and
+ * writing Java classes with no intermediate transformation.
+ *
+ * @author Eric Bruneton
+ */
+@Fork(1)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 30, time = 1, timeUnit = TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AdapterBenchmark extends AbstractBenchmark {
+
+ private Adapter asm4dot0;
+ private Adapter asm5dot0;
+ private Adapter asm6dot0;
+ private Adapter asm7dot0;
+ private Adapter asm8dot0;
+ private Adapter asm9dot0;
+ private Adapter asmCurrent;
+ private Adapter aspectJBcel;
+ private Adapter bcel;
+ private Adapter javassist;
+ private Adapter serp;
+
+ public AdapterBenchmark() {
+ super("org.objectweb.asm.benchmarks.AsmAdapter");
+ }
+
+ /**
+ * Prepares the benchmark by creating an {@link Adapter} for each library to be tested, and by
+ * loading some test data (i.e. some classes to "adapt").
+ *
+ * @throws Exception if an error occurs.
+ */
+ @Setup
+ public void prepare() throws Exception {
+ asm4dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V4_0).newAsmBenchmark();
+ asm5dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
+ asm6dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
+ asm7dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V7_0).newAsmBenchmark();
+ asm8dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V8_0).newAsmBenchmark();
+ asm9dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V9_0).newAsmBenchmark();
+ asmCurrent = (Adapter) new AsmBenchmarkFactory(AsmVersion.V_CURRENT).newAsmBenchmark();
+ aspectJBcel = new AspectjBcelAdapter();
+ bcel = new BcelAdapter();
+ javassist = new JavassistAdapter();
+ serp = new SerpAdapter();
+
+ // Check that the correct versions of ASM have been loaded.
+ if (!asm4dot0.getVersion().equals("ASM4")
+ || !asm5dot0.getVersion().equals("ASM5")
+ || !asm6dot0.getVersion().equals("ASM6")
+ || !asm7dot0.getVersion().equals("ASM7")
+ || !asm8dot0.getVersion().equals("ASM8")
+ || !asm9dot0.getVersion().equals("ASM9")
+ || !asmCurrent.getVersion().equals("ASM9")) {
+ throw new IllegalStateException();
+ }
+
+ prepareClasses();
+ }
+
+ @Benchmark
+ public void getClassInfo_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassObjectModel_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.getClassObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_aspectJBcel(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(aspectJBcel.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_bcel(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(bcel.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_javassist(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(javassist.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_serp(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(serp.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeFrames_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.readAndWriteWithComputeFrames(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_aspectJBcel(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(aspectJBcel.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_bcel(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(bcel.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithComputeMaxs_serp(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(serp.readAndWrite(classFile, /* computeMaxs = */ true));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm4_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm4dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm5dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm6dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm7dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm8dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asm9dot0.readAndWriteWithObjectModel(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithObjectModel_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : classFiles) {
+ blackhole.consume(asmCurrent.readAndWriteWithObjectModel(classFile));
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmarkJava8.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmarkJava8.java
new file mode 100644
index 00000000..2e0f9d72
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AdapterBenchmarkJava8.java
@@ -0,0 +1,258 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * A benchmark to measure the performance of ASM when reading and writing Java 8 classes (containing
+ * stack map frames and invokedynamic instructions) with no intermediate transformation.
+ *
+ * @author Eric Bruneton
+ */
+@Fork(1)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 30, time = 1, timeUnit = TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class AdapterBenchmarkJava8 extends AbstractBenchmark {
+
+ private Adapter asm5dot0;
+ private Adapter asm6dot0;
+ private Adapter asm7dot0;
+ private Adapter asm8dot0;
+ private Adapter asm9dot0;
+ private Adapter asmCurrent;
+
+ public AdapterBenchmarkJava8() {
+ super("org.objectweb.asm.benchmarks.AsmAdapter");
+ }
+
+ /**
+ * Prepares the benchmark by creating an {@link Adapter} for each library to be tested, and by
+ * loading some test data (i.e. some classes to "adapt").
+ *
+ * @throws Exception if an error occurs.
+ */
+ @Setup
+ public void prepare() throws Exception {
+ asm5dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
+ asm6dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
+ asm7dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V7_0).newAsmBenchmark();
+ asm8dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V8_0).newAsmBenchmark();
+ asm9dot0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V9_0).newAsmBenchmark();
+ asmCurrent = (Adapter) new AsmBenchmarkFactory(AsmVersion.V_CURRENT).newAsmBenchmark();
+
+ // Check that the correct versions of ASM have been loaded.
+ if (!asm5dot0.getVersion().equals("ASM5")
+ || !asm6dot0.getVersion().equals("ASM6")
+ || !asm7dot0.getVersion().equals("ASM7")
+ || !asm8dot0.getVersion().equals("ASM8")
+ || !asm9dot0.getVersion().equals("ASM9")
+ || !asmCurrent.getVersion().equals("ASM9")) {
+ throw new IllegalStateException();
+ }
+
+ prepareClasses();
+ }
+
+ @Benchmark
+ public void getClassInfo_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm5dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm6dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm7dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm8dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm9dot0.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void getClassInfo_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asmCurrent.getClassInfo(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm5dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm6dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm7dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm8dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm9dot0.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void read_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asmCurrent.read(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm5dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm6dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm7dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm8dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm9dot0.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWrite_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asmCurrent.readAndWrite(classFile, /* computeMaxs = */ false));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm5_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm5dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm6_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm6dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm7_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm7dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm8_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm8dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asm9_0(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asm9dot0.readAndWriteWithCopyPool(classFile));
+ }
+ }
+
+ @Benchmark
+ public void readAndWriteWithCopyPool_asmCurrent(final Blackhole blackhole) {
+ for (byte[] classFile : java8classFiles) {
+ blackhole.consume(asmCurrent.readAndWriteWithCopyPool(classFile));
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java
new file mode 100644
index 00000000..078dbd71
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmAdapter.java
@@ -0,0 +1,447 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+import org.objectweb.asm.tree.ClassNode;
+
+/**
+ * An {@link Adapter} implemented with the ASM library.
+ *
+ * @author Eric Bruneton
+ */
+public class AsmAdapter extends Adapter {
+
+ private int asmApi;
+
+ @Override
+ public String getVersion() {
+ for (int i = 9; i >= 4; --i) {
+ try {
+ String version = "ASM" + i;
+ if (Opcodes.class.getField(version) != null) {
+ asmApi = Opcodes.class.getField(version).getInt(null);
+ return version;
+ }
+ } catch (NoSuchFieldException e) {
+ continue;
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }
+ return "";
+ }
+
+ @Override
+ public ClassInfo getClassInfo(final byte[] classFile) {
+ ClassReader classReader = new ClassReader(classFile);
+ return new ClassInfo(
+ classReader.getAccess(),
+ classReader.getClassName(),
+ classReader.getSuperName(),
+ classReader.getInterfaces());
+ }
+
+ @Override
+ public Object getClassObjectModel(final byte[] classFile) {
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classFile).accept(classNode, 0);
+ return classNode;
+ }
+
+ @Override
+ public int read(final byte[] classFile) {
+ CountingVisitor countingVisitor = new CountingVisitor(asmApi);
+ new ClassReader(classFile).accept(countingVisitor, 0);
+ return countingVisitor.count;
+ }
+
+ @Override
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMaxs) {
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(computeMaxs ? ClassWriter.COMPUTE_MAXS : 0);
+ classReader.accept(classWriter, 0);
+ return classWriter.toByteArray();
+ }
+
+ @Override
+ public byte[] readAndWriteWithComputeFrames(final byte[] classFile) {
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classReader.accept(classWriter, 0);
+ return classWriter.toByteArray();
+ }
+
+ @Override
+ public byte[] readAndWriteWithCopyPool(final byte[] classFile) {
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(classReader, 0);
+ classReader.accept(classWriter, 0);
+ return classWriter.toByteArray();
+ }
+
+ @Override
+ public byte[] readAndWriteWithObjectModel(final byte[] classFile) {
+ ClassWriter classWriter = new ClassWriter(0);
+ ClassNode classNode = new ClassNode();
+ new ClassReader(classFile).accept(classNode, 0);
+ classNode.accept(classWriter);
+ return classWriter.toByteArray();
+ }
+
+ private static class CountingVisitor extends ClassVisitor {
+
+ int count;
+
+ AnnotationVisitor annotationVisitor =
+ new AnnotationVisitor(api) {
+
+ @Override
+ public void visit(final String name, final Object value) {
+ ++count;
+ }
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ ++count;
+ return this;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ ++count;
+ return this;
+ }
+ };
+
+ public CountingVisitor(final int api) {
+ super(api);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ ++count;
+ }
+
+ @Override
+ public void visitSource(final String source, final String debug) {
+ ++count;
+ }
+
+ @Override
+ public ModuleVisitor visitModule(final String name, final int access, final String version) {
+ ++count;
+ return null;
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitInnerClass(
+ final String name, final String outerName, final String innerName, final int access) {
+ ++count;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ ++count;
+ return new FieldVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+ };
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ return new MethodVisitor(api) {
+
+ @Override
+ public void visitParameter(final String name, final int access) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitFrame(
+ final int type,
+ final int numLocal,
+ final Object[] local,
+ final int numStack,
+ final Object[] stack) {
+ ++count;
+ }
+
+ @Override
+ public void visitInsn(final int opcode) {
+ ++count;
+ }
+
+ @Override
+ public void visitIntInsn(final int opcode, final int operand) {
+ ++count;
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int varIndex) {
+ ++count;
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ ++count;
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ ++count;
+ }
+
+ @Override
+ @Deprecated
+ public void visitMethodInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ ++count;
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ ++count;
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ ++count;
+ }
+
+ @Override
+ public void visitJumpInsn(final int opcode, final Label label) {
+ ++count;
+ }
+
+ @Override
+ public void visitLabel(final Label label) {
+ ++count;
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ ++count;
+ }
+
+ @Override
+ public void visitIincInsn(final int varIndex, final int increment) {
+ ++count;
+ }
+
+ @Override
+ public void visitTableSwitchInsn(
+ final int min, final int max, final Label dflt, final Label... labels) {
+ ++count;
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(
+ final Label dflt, final int[] keys, final Label[] labels) {
+ ++count;
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ ++count;
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ ++count;
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ ++count;
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ ++count;
+ }
+ };
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmFactory.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmFactory.java
new file mode 100644
index 00000000..c33aef73
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmFactory.java
@@ -0,0 +1,68 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.ClassNode;
+
+/** A {@link Factory} implemented with the ASM library. */
+public class AsmFactory implements Factory {
+
+ @Override
+ public String getVersion() {
+ for (int i = 9; i >= 4; --i) {
+ try {
+ String version = "ASM" + i;
+ if (Opcodes.class.getField(version) != null) {
+ return version;
+ }
+ } catch (NoSuchFieldException e) {
+ continue;
+ }
+ }
+ return "";
+ }
+
+ @Override
+ public Object newClass(final byte[] classFile) {
+ ClassReader classReader = new ClassReader(classFile);
+ ClassWriter classWriter = new ClassWriter(0);
+ classReader.accept(classWriter, 0);
+ return classWriter;
+ }
+
+ @Override
+ public Object newClassNode(final byte[] classFile) {
+ ClassReader classReader = new ClassReader(classFile);
+ ClassNode classNode = new ClassNode();
+ classReader.accept(classNode, 0);
+ return classNode;
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmGenerator.java
new file mode 100644
index 00000000..025aa87d
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AsmGenerator.java
@@ -0,0 +1,87 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A "Hello World!" class generator using the ASM library.
+ *
+ * @author Eric Bruneton
+ */
+public class AsmGenerator extends Generator {
+
+ @Override
+ public String getVersion() {
+ for (int i = 9; i >= 5; --i) {
+ try {
+ String version = "ASM" + i;
+ if (Opcodes.class.getField(version) != null) {
+ return version;
+ }
+ } catch (NoSuchFieldException e) {
+ continue;
+ }
+ }
+ return "";
+ }
+
+ @Override
+ public byte[] generateClass() {
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+ classWriter.visit(
+ Opcodes.V1_1, Opcodes.ACC_PUBLIC, "HelloWorld", null, "java/lang/Object", null);
+ classWriter.visitSource("HelloWorld.java", null);
+
+ MethodVisitor methodVisitor =
+ classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ methodVisitor =
+ classWriter.visitMethod(
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+ methodVisitor.visitFieldInsn(
+ Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("Hello world!");
+ methodVisitor.visitMethodInsn(
+ Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitInsn(Opcodes.RETURN);
+ methodVisitor.visitMaxs(0, 0);
+ methodVisitor.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelAdapter.java
new file mode 100644
index 00000000..2aae5318
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelAdapter.java
@@ -0,0 +1,82 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import org.aspectj.apache.bcel.classfile.ClassFormatException;
+import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.generic.ClassGen;
+import org.aspectj.apache.bcel.generic.InstructionHandle;
+import org.aspectj.apache.bcel.generic.InstructionList;
+import org.aspectj.apache.bcel.generic.MethodGen;
+
+/**
+ * An {@link Adapter} implemented with the AspectJ BCEL library.
+ *
+ * @author Eric Bruneton
+ */
+public class AspectjBcelAdapter extends Adapter {
+
+ @Override
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMaxs) {
+ JavaClass javaClass;
+ try {
+ javaClass = new ClassParser(new ByteArrayInputStream(classFile), "class-name").parse();
+ } catch (ClassFormatException | IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ ClassGen classGen = new ClassGen(javaClass);
+ ConstantPool constantPool = classGen.getConstantPool();
+ for (Method method : classGen.getMethods()) {
+ MethodGen methodGen = new MethodGen(method, classGen.getClassName(), constantPool);
+ if (method.getLocalVariableTable() == null) {
+ methodGen.removeLocalVariables();
+ }
+ if (method.getLineNumberTable() == null) {
+ methodGen.removeLineNumbers();
+ }
+ InstructionList insnList = methodGen.getInstructionList();
+ if (insnList != null) {
+ InstructionHandle insnHandle = insnList.getStart();
+ while (insnHandle != null) {
+ insnHandle = insnHandle.getNext();
+ }
+ if (computeMaxs) {
+ methodGen.setMaxStack();
+ methodGen.setMaxLocals();
+ }
+ }
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ return classGen.getJavaClass().getBytes();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelGenerator.java
new file mode 100644
index 00000000..3288f80a
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/AspectjBcelGenerator.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.generic.ArrayType;
+import org.aspectj.apache.bcel.generic.ClassGen;
+import org.aspectj.apache.bcel.generic.InstructionFactory;
+import org.aspectj.apache.bcel.generic.InstructionList;
+import org.aspectj.apache.bcel.generic.MethodGen;
+import org.aspectj.apache.bcel.generic.Type;
+
+/**
+ * A "Hello World!" class generator using the AspectJ BCEL library.
+ *
+ * @author Eric Bruneton
+ */
+public class AspectjBcelGenerator extends Generator {
+
+ private static final Type PRINT_STREAM_TYPE = Type.getType("Ljava/io/PrintStream;");
+
+ @Override
+ public byte[] generateClass() {
+ ClassGen classGen =
+ new ClassGen(
+ "HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null);
+
+ classGen.addEmptyConstructor(Constants.ACC_PUBLIC);
+
+ ConstantPool constantPoolGen = classGen.getConstantPool();
+ InstructionList insnList = new InstructionList();
+ InstructionFactory insnFactory = new InstructionFactory(classGen);
+
+ MethodGen methodGen =
+ new MethodGen(
+ Constants.ACC_STATIC | Constants.ACC_PUBLIC,
+ Type.VOID,
+ new Type[] {new ArrayType(Type.STRING, 1)},
+ null,
+ "main",
+ "HelloWorld",
+ insnList,
+ constantPoolGen);
+ insnList.append(insnFactory.createGetStatic("java/lang/System", "out", PRINT_STREAM_TYPE));
+ insnList.append(insnFactory.createConstant("Hello world!"));
+ insnList.append(
+ insnFactory.createInvoke(
+ "java.io.PrintStream",
+ "println",
+ Type.VOID,
+ new Type[] {Type.STRING},
+ Constants.INVOKESPECIAL));
+
+ methodGen.setMaxStack();
+ classGen.addMethod(methodGen.getMethod());
+
+ return classGen.getJavaClass().getBytes();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelAdapter.java
new file mode 100644
index 00000000..04dd541d
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelAdapter.java
@@ -0,0 +1,82 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.ClassGen;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.InstructionHandle;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.MethodGen;
+import org.aspectj.apache.bcel.classfile.ClassFormatException;
+
+/**
+ * An {@link Adapter} implemented with the BCEL library.
+ *
+ * @author Eric Bruneton
+ */
+public class BcelAdapter extends Adapter {
+
+ @Override
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMaxs) {
+ JavaClass javaClass;
+ try {
+ javaClass = new ClassParser(new ByteArrayInputStream(classFile), "class-name").parse();
+ } catch (ClassFormatException | IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ ClassGen classGen = new ClassGen(javaClass);
+ ConstantPoolGen constantPoolGen = classGen.getConstantPool();
+ for (Method method : classGen.getMethods()) {
+ MethodGen methodGen = new MethodGen(method, classGen.getClassName(), constantPoolGen);
+ if (method.getLocalVariableTable() == null) {
+ methodGen.removeLocalVariables();
+ }
+ if (method.getLineNumberTable() == null) {
+ methodGen.removeLineNumbers();
+ }
+ InstructionList insnList = methodGen.getInstructionList();
+ if (insnList != null) {
+ InstructionHandle insnHandle = insnList.getStart();
+ while (insnHandle != null) {
+ insnHandle = insnHandle.getNext();
+ }
+ if (computeMaxs) {
+ methodGen.setMaxStack();
+ methodGen.setMaxLocals();
+ }
+ }
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ return classGen.getJavaClass().getBytes();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelGenerator.java
new file mode 100644
index 00000000..1a82b7a8
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/BcelGenerator.java
@@ -0,0 +1,85 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.apache.bcel.Const;
+import org.apache.bcel.generic.ArrayType;
+import org.apache.bcel.generic.ClassGen;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.InstructionFactory;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.MethodGen;
+import org.apache.bcel.generic.PUSH;
+import org.apache.bcel.generic.Type;
+
+/**
+ * A "Hello World!" class generator using the BCEL library.
+ *
+ * @author Eric Bruneton
+ */
+public class BcelGenerator extends Generator {
+
+ private static final Type PRINT_STREAM_TYPE = Type.getType("Ljava/io/PrintStream;");
+
+ @Override
+ public byte[] generateClass() {
+ ClassGen classGen =
+ new ClassGen("HelloWorld", "java/lang/Object", "HelloWorld.java", Const.ACC_PUBLIC, null);
+
+ classGen.addEmptyConstructor(Const.ACC_PUBLIC);
+
+ ConstantPoolGen constantPoolGen = classGen.getConstantPool();
+ InstructionList insnList = new InstructionList();
+ InstructionFactory insnFactory = new InstructionFactory(classGen);
+
+ MethodGen methodGen =
+ new MethodGen(
+ Const.ACC_STATIC | Const.ACC_PUBLIC,
+ Type.VOID,
+ new Type[] {new ArrayType(Type.STRING, 1)},
+ null,
+ "main",
+ "HelloWorld",
+ insnList,
+ constantPoolGen);
+ insnList.append(insnFactory.createGetStatic("java/lang/System", "out", PRINT_STREAM_TYPE));
+ insnList.append(new PUSH(constantPoolGen, "Hello world!"));
+ insnList.append(
+ insnFactory.createInvoke(
+ "java.io.PrintStream",
+ "println",
+ Type.VOID,
+ new Type[] {Type.STRING},
+ Const.INVOKESPECIAL));
+
+ methodGen.setMaxStack();
+ classGen.addMethod(methodGen.getMethod());
+
+ return classGen.getJavaClass().getBytes();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CojenGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CojenGenerator.java
new file mode 100644
index 00000000..4e451ded
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CojenGenerator.java
@@ -0,0 +1,71 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import org.cojen.classfile.ClassFile;
+import org.cojen.classfile.CodeBuilder;
+import org.cojen.classfile.MethodInfo;
+import org.cojen.classfile.Modifiers;
+import org.cojen.classfile.TypeDesc;
+
+/**
+ * A "Hello World!" class generator using the Cojen library.
+ *
+ * @author Eric Bruneton
+ */
+public class CojenGenerator extends Generator {
+
+ private static final TypeDesc PRINT_STREAM = TypeDesc.forClass("java.io.PrintStream");
+
+ @Override
+ public byte[] generateClass() {
+ ClassFile classFile = new ClassFile("HelloWorld");
+
+ classFile.setSourceFile("HelloWorld.java");
+
+ classFile.addDefaultConstructor();
+
+ TypeDesc[] params = new TypeDesc[] {TypeDesc.STRING.toArrayType()};
+ MethodInfo methodInfo = classFile.addMethod(Modifiers.PUBLIC_STATIC, "main", null, params);
+ CodeBuilder codeBuilder = new CodeBuilder(methodInfo);
+ codeBuilder.loadStaticField("java.lang.System", "out", PRINT_STREAM);
+ codeBuilder.loadConstant("Hello world!");
+ codeBuilder.invokeVirtual(PRINT_STREAM, "println", null, new TypeDesc[] {TypeDesc.STRING});
+ codeBuilder.returnVoid();
+
+ try {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ classFile.writeTo(byteArrayOutputStream);
+ return byteArrayOutputStream.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException("Class generation failed", e);
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CsgBytecodeGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CsgBytecodeGenerator.java
new file mode 100644
index 00000000..6bb7cb50
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/CsgBytecodeGenerator.java
@@ -0,0 +1,71 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import com.claritysys.jvm.builder.CodeBuilder;
+import com.claritysys.jvm.classfile.CfMethod;
+import com.claritysys.jvm.classfile.ClassFile;
+import com.claritysys.jvm.classfile.ConstantPool;
+import com.claritysys.jvm.classfile.JVM;
+
+/**
+ * A "Hello World!" class generator using the CSG Bytecode library.
+ *
+ * @author Eric Bruneton
+ */
+public class CsgBytecodeGenerator extends Generator {
+
+ @Override
+ public byte[] generateClass() {
+ ClassFile classFile = new ClassFile("HelloWorld", "java/lang/Object", "HelloWorld.java");
+ ConstantPool constantPool = classFile.getConstantPool();
+
+ CfMethod method = classFile.addMethod(JVM.ACC_PUBLIC, "<init>", "()V");
+ CodeBuilder code = new CodeBuilder(method);
+ code.add(JVM.ALOAD_0);
+ code.add(
+ JVM.INVOKESPECIAL, constantPool.addMethodRef(false, "java/lang/Object", "<init>", "()V"));
+ code.add(JVM.RETURN);
+ code.flush();
+
+ method = classFile.addMethod(JVM.ACC_PUBLIC + JVM.ACC_STATIC, "main", "([Ljava/lang/String;)V");
+ code = new CodeBuilder(method);
+ code.add(
+ JVM.GETSTATIC,
+ constantPool.addFieldRef("java/lang/System", "out", "Ljava/io/PrintStream;"));
+ code.add(JVM.LDC, "Hello world!");
+ code.add(
+ JVM.INVOKEVIRTUAL,
+ constantPool.addMethodRef(
+ false, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
+ code.add(JVM.RETURN);
+ code.flush();
+
+ return classFile.writeToArray();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Factory.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Factory.java
new file mode 100644
index 00000000..557f9a17
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Factory.java
@@ -0,0 +1,59 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+/**
+ * A factory of in-memory Java class file models.
+ *
+ * @author Eric Bruneton
+ */
+public interface Factory {
+
+ /**
+ * Returns the version of this factory.
+ *
+ * @return the version of this factory.
+ */
+ String getVersion();
+
+ /**
+ * Returns a "high level" representation of the given class.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return a "high level" representation of the given class.
+ */
+ Object newClass(final byte[] classFile);
+
+ /**
+ * Returns a tree structure representation of the given class.
+ *
+ * @param classFile a JVMS ClassFile structure
+ * @return a tree structure representation of the given class.
+ */
+ Object newClassNode(final byte[] classFile);
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Generator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Generator.java
new file mode 100644
index 00000000..1108d47d
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/Generator.java
@@ -0,0 +1,52 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+/**
+ * An abstract "Hello World!" class generator.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class Generator {
+
+ /**
+ * Returns the version of this generator.
+ *
+ * @return the version of this generator, or an empty string if there is no version.
+ */
+ public String getVersion() {
+ return "";
+ }
+
+ /**
+ * Generates a "Hello World!" class.
+ *
+ * @return the JVMS ClassFile structure of the generated class.
+ */
+ public abstract byte[] generateClass();
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GeneratorBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GeneratorBenchmark.java
new file mode 100644
index 00000000..57308eae
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GeneratorBenchmark.java
@@ -0,0 +1,172 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * A benchmark to measure the performance of several libraries when generating a "Hello World!"
+ * class.
+ *
+ * @author Eric Bruneton
+ */
+@Fork(1)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 30, time = 1, timeUnit = TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class GeneratorBenchmark extends AbstractBenchmark {
+
+ private Generator asm5dot0;
+ private Generator asm6dot0;
+ private Generator asm7dot0;
+ private Generator asm8dot0;
+ private Generator asm9dot0;
+ private Generator asmCurrent;
+ private Generator aspectJBcel;
+ private Generator bcel;
+ private Generator cojen;
+ private Generator csgBytecode;
+ private Generator gnuByteCode;
+ private Generator jclassLib;
+ private Generator jiapi;
+ private Generator mozillaClassFile;
+
+ public GeneratorBenchmark() {
+ super("org.objectweb.asm.benchmarks.AsmGenerator");
+ }
+
+ /**
+ * Prepares the benchmark by creating a {@link Generator} for each library to be tested.
+ *
+ * @throws Exception if an error occurs.
+ */
+ @Setup
+ public void prepare() throws Exception {
+ asm5dot0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
+ asm6dot0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
+ asm7dot0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V7_0).newAsmBenchmark();
+ asm8dot0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V8_0).newAsmBenchmark();
+ asm9dot0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V9_0).newAsmBenchmark();
+ asmCurrent = (Generator) new AsmBenchmarkFactory(AsmVersion.V_CURRENT).newAsmBenchmark();
+ aspectJBcel = new AspectjBcelGenerator();
+ bcel = new BcelGenerator();
+ cojen = new CojenGenerator();
+ csgBytecode = new CsgBytecodeGenerator();
+ gnuByteCode = new GnuByteCodeGenerator();
+ jclassLib = new JClassLibGenerator();
+ jiapi = new JiapiGenerator();
+ mozillaClassFile = new MozillaClassFileGenerator();
+
+ // Check that the correct versions of ASM have been loaded.
+ if (!asm5dot0.getVersion().equals("ASM5")
+ || !asm6dot0.getVersion().equals("ASM6")
+ || !asm7dot0.getVersion().equals("ASM7")
+ || !asm8dot0.getVersion().equals("ASM8")
+ || !asm9dot0.getVersion().equals("ASM9")
+ || !asmCurrent.getVersion().equals("ASM9")) {
+ throw new IllegalStateException();
+ }
+ }
+
+ @Benchmark
+ public byte[] asm5_0() {
+ return asm5dot0.generateClass();
+ }
+
+ @Benchmark
+ public byte[] asm6_0() {
+ return asm6dot0.generateClass();
+ }
+
+ @Benchmark
+ public byte[] asm7_0() {
+ return asm7dot0.generateClass();
+ }
+
+ @Benchmark
+ public byte[] asm8_0() {
+ return asm8dot0.generateClass();
+ }
+
+ @Benchmark
+ public byte[] asm9_0() {
+ return asm9dot0.generateClass();
+ }
+
+ @Benchmark
+ public byte[] asmCurrent() {
+ return asmCurrent.generateClass();
+ }
+
+ @Benchmark
+ public byte[] aspectJBcel() {
+ return aspectJBcel.generateClass();
+ }
+
+ @Benchmark
+ public byte[] bcel() {
+ return bcel.generateClass();
+ }
+
+ @Benchmark
+ public byte[] cojen() {
+ return cojen.generateClass();
+ }
+
+ @Benchmark
+ public byte[] csgBytecode() {
+ return csgBytecode.generateClass();
+ }
+
+ @Benchmark
+ public byte[] gnuByteCode() {
+ return gnuByteCode.generateClass();
+ }
+
+ @Benchmark
+ public byte[] jclassLib() {
+ return jclassLib.generateClass();
+ }
+
+ @Benchmark
+ public byte[] jiapi() {
+ return jiapi.generateClass();
+ }
+
+ @Benchmark
+ public byte[] mozillaClassFile() {
+ return mozillaClassFile.generateClass();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GnuByteCodeGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GnuByteCodeGenerator.java
new file mode 100644
index 00000000..a54b0093
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/GnuByteCodeGenerator.java
@@ -0,0 +1,76 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (classType) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import gnu.bytecode.Access;
+import gnu.bytecode.ClassType;
+import gnu.bytecode.CodeAttr;
+import gnu.bytecode.Field;
+import gnu.bytecode.Method;
+import gnu.bytecode.Type;
+
+/**
+ * A "Hello World!" class generator using the GNU ByteCode library.
+ *
+ * @author Eric Bruneton
+ */
+public class GnuByteCodeGenerator extends Generator {
+
+ private static final Method OBJECT_CONSTRUCTOR = Type.pointer_type.getDeclaredMethod("<init>", 0);
+ private static final Field OUT_FIELD = ClassType.make("java.lang.System").getField("out");
+ private static final Method PRINTLN_METHOD =
+ ClassType.make("java.io.PrintStream")
+ .getDeclaredMethod("println", new Type[] {Type.string_type});
+
+ @Override
+ public byte[] generateClass() {
+ ClassType classType = new ClassType("HelloWorld");
+ classType.setSuper("java.lang.Object");
+ classType.setModifiers(Access.PUBLIC);
+ classType.setSourceFile("HelloWorld.java");
+
+ Method method = classType.addMethod("<init>", "()V", Access.PUBLIC);
+ CodeAttr code = method.startCode();
+ code.pushScope();
+ code.emitPushThis();
+ code.emitInvokeSpecial(OBJECT_CONSTRUCTOR);
+ code.emitReturn();
+ code.popScope();
+
+ method = classType.addMethod("main", "([Ljava/lang/String;)V", Access.PUBLIC | Access.STATIC);
+ code = method.startCode();
+ code.pushScope();
+ code.emitGetStatic(OUT_FIELD);
+ code.emitPushString("Hello world!");
+ code.emitInvokeVirtual(PRINTLN_METHOD);
+ code.emitReturn();
+ code.popScope();
+
+ return classType.writeToArray();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java
new file mode 100644
index 00000000..fc2b0a73
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JClassLibGenerator.java
@@ -0,0 +1,143 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import org.gjt.jclasslib.bytecode.ImmediateByteInstruction;
+import org.gjt.jclasslib.bytecode.ImmediateShortInstruction;
+import org.gjt.jclasslib.bytecode.Opcodes;
+import org.gjt.jclasslib.bytecode.SimpleInstruction;
+import org.gjt.jclasslib.io.ByteCodeWriter;
+import org.gjt.jclasslib.structures.AccessFlags;
+import org.gjt.jclasslib.structures.AttributeInfo;
+import org.gjt.jclasslib.structures.CPInfo;
+import org.gjt.jclasslib.structures.ClassFile;
+import org.gjt.jclasslib.structures.ConstantPoolUtil;
+import org.gjt.jclasslib.structures.InvalidByteCodeException;
+import org.gjt.jclasslib.structures.MethodInfo;
+import org.gjt.jclasslib.structures.attributes.CodeAttribute;
+import org.gjt.jclasslib.structures.attributes.SourceFileAttribute;
+import org.gjt.jclasslib.structures.constants.ConstantStringInfo;
+
+/**
+ * A "Hello World!" class generator using the JClassLib library.
+ *
+ * @author Eric Bruneton
+ */
+public class JClassLibGenerator extends Generator {
+
+ @Override
+ public byte[] generateClass() {
+ try {
+ ClassFile classFile = new ClassFile();
+ classFile.setConstantPool(new CPInfo[0]);
+ ConstantPoolUtil.addConstantUTF8Info(classFile, "", 0); // dummy constant
+ classFile.setMajorVersion(45);
+ classFile.setMinorVersion(3);
+ classFile.setAccessFlags(AccessFlags.ACC_PUBLIC);
+ classFile.setThisClass(ConstantPoolUtil.addConstantClassInfo(classFile, "HelloWorld", 0));
+ classFile.setSuperClass(
+ ConstantPoolUtil.addConstantClassInfo(classFile, "java/lang/Object", 0));
+
+ SourceFileAttribute sourceFileAttribute = new SourceFileAttribute();
+ sourceFileAttribute.setAttributeNameIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, SourceFileAttribute.ATTRIBUTE_NAME, 0));
+ sourceFileAttribute.setSourcefileIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, "HelloWorld.java", 0));
+
+ MethodInfo methodInfo1 = new MethodInfo();
+ methodInfo1.setAccessFlags(AccessFlags.ACC_PUBLIC);
+ methodInfo1.setNameIndex(ConstantPoolUtil.addConstantUTF8Info(classFile, "<init>", 0));
+ methodInfo1.setDescriptorIndex(ConstantPoolUtil.addConstantUTF8Info(classFile, "()V", 0));
+ CodeAttribute codeAttribute1 = new CodeAttribute();
+ codeAttribute1.setAttributeNameIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, CodeAttribute.ATTRIBUTE_NAME, 0));
+ codeAttribute1.setCode(
+ ByteCodeWriter.writeByteCode(
+ Arrays.asList(
+ new SimpleInstruction(Opcodes.OPCODE_ALOAD_0),
+ new ImmediateShortInstruction(
+ Opcodes.OPCODE_INVOKESPECIAL,
+ ConstantPoolUtil.addConstantMethodrefInfo(
+ classFile, "java/lang/Object", "<init>", "()V", 0)),
+ new SimpleInstruction(Opcodes.OPCODE_RETURN))));
+ codeAttribute1.setMaxStack(1);
+ codeAttribute1.setMaxLocals(1);
+ methodInfo1.setAttributes(new AttributeInfo[] {codeAttribute1});
+
+ ConstantStringInfo constantStringInfo = new ConstantStringInfo();
+ constantStringInfo.setStringIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, "Hello world!", 0));
+
+ MethodInfo methodInfo2 = new MethodInfo();
+ methodInfo2.setAccessFlags(AccessFlags.ACC_PUBLIC | AccessFlags.ACC_STATIC);
+ methodInfo2.setNameIndex(ConstantPoolUtil.addConstantUTF8Info(classFile, "main", 0));
+ methodInfo2.setDescriptorIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, "([Ljava/lang/String;)V", 0));
+ CodeAttribute codeAttribute2 = new CodeAttribute();
+ codeAttribute2.setAttributeNameIndex(
+ ConstantPoolUtil.addConstantUTF8Info(classFile, CodeAttribute.ATTRIBUTE_NAME, 0));
+ codeAttribute2.setCode(
+ ByteCodeWriter.writeByteCode(
+ Arrays.asList(
+ new ImmediateShortInstruction(
+ Opcodes.OPCODE_GETSTATIC,
+ ConstantPoolUtil.addConstantFieldrefInfo(
+ classFile, "java/lang/System", "out", "Ljava/io/PrintStream;", 0)),
+ new ImmediateByteInstruction(
+ Opcodes.OPCODE_LDC,
+ false,
+ ConstantPoolUtil.addConstantPoolEntry(classFile, constantStringInfo, 0)),
+ new ImmediateShortInstruction(
+ Opcodes.OPCODE_INVOKEVIRTUAL,
+ ConstantPoolUtil.addConstantMethodrefInfo(
+ classFile,
+ "java/io/PrintStream",
+ "println",
+ "(Ljava/lang/String;)V",
+ 0)))));
+ codeAttribute2.setMaxStack(2);
+ codeAttribute2.setMaxLocals(1);
+ methodInfo2.setAttributes(new AttributeInfo[] {codeAttribute2});
+
+ classFile.setMethods(new MethodInfo[] {methodInfo1, methodInfo2});
+ classFile.setAttributes(new AttributeInfo[] {sourceFileAttribute});
+
+ try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
+ classFile.write(dataOutputStream);
+ return byteArrayOutputStream.toByteArray();
+ }
+ } catch (IOException | InvalidByteCodeException e) {
+ throw new RuntimeException("Class generation failed", e);
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java
new file mode 100644
index 00000000..89c6e2e6
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JavassistAdapter.java
@@ -0,0 +1,57 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import javassist.ClassPool;
+import javassist.CtClass;
+
+/**
+ * An {@link Adapter} implemented with the Javassist library.
+ *
+ * @author Eric Bruneton
+ */
+public class JavassistAdapter extends Adapter {
+
+ @Override
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMax) {
+ try {
+ CtClass ctClass = new ClassPool().makeClass(new ByteArrayInputStream(classFile));
+ try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream)) {
+ ctClass.getClassFile().write(dataOutputStream);
+ return byteArrayOutputStream.toByteArray();
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JiapiGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JiapiGenerator.java
new file mode 100644
index 00000000..854b7e1b
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/JiapiGenerator.java
@@ -0,0 +1,78 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.lang.reflect.Modifier;
+import net.sf.jiapi.reflect.InstructionFactory;
+import net.sf.jiapi.reflect.InstructionList;
+import net.sf.jiapi.reflect.JiapiClass;
+import net.sf.jiapi.reflect.JiapiMethod;
+import net.sf.jiapi.reflect.MethodExistsException;
+import net.sf.jiapi.reflect.Signature;
+
+/**
+ * A "Hello World!" class generator using the Jiapi library.
+ *
+ * @author Eric Bruneton
+ */
+public class JiapiGenerator extends Generator {
+
+ private static final Signature EMPTY_SIGNATURE = new Signature("()V");
+ private static final Signature MAIN_SIGNATURE = new Signature("([Ljava/lang/String;)V");
+ private static final Signature PRINTLN_SIGNATURE = new Signature("(Ljava/lang/String;)V");
+
+ @Override
+ public byte[] generateClass() {
+ try {
+ JiapiClass jiapiClass = JiapiClass.createClass("HelloWorld");
+
+ // No API to set SourceFile!
+
+ JiapiMethod method = jiapiClass.addMethod(Modifier.PUBLIC, "<init>", EMPTY_SIGNATURE);
+ InstructionList insnList = method.getInstructionList();
+ InstructionFactory insnFactory = insnList.getInstructionFactory();
+ insnList.add(insnFactory.aload(0));
+ insnList.add(insnFactory.invoke(0, "java/lang/Object", "<init>", EMPTY_SIGNATURE));
+ insnList.add(insnFactory.returnMethod(method));
+
+ method = jiapiClass.addMethod(Modifier.PUBLIC | Modifier.STATIC, "main", MAIN_SIGNATURE);
+ insnList = method.getInstructionList();
+ insnFactory = insnList.getInstructionFactory();
+ insnList.add(
+ insnFactory.getField(
+ Modifier.STATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
+ insnList.add(insnFactory.pushConstant("Hello world!"));
+ insnList.add(insnFactory.invoke(0, "java/io/PrintStream", "println", PRINTLN_SIGNATURE));
+ insnList.add(insnFactory.returnMethod(method));
+
+ return jiapiClass.getByteCode();
+ } catch (MethodExistsException e) {
+ throw new RuntimeException("Class generation failed", e);
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryBenchmark.java
new file mode 100644
index 00000000..0ac6328f
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryBenchmark.java
@@ -0,0 +1,190 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * A benchmark to measure the memory usage of several Java bytecode libraries when reading Java
+ * classes.
+ *
+ * @author Eric Bruneton
+ */
+@Fork(1)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class MemoryBenchmark extends AbstractBenchmark {
+
+ private Factory asm4dot0;
+ private Factory asm5dot0;
+ private Factory asm6dot0;
+ private Factory asm7dot0;
+ private Factory asm8dot0;
+ private Factory asm9dot0;
+ private Factory asmCurrent;
+
+ public MemoryBenchmark() {
+ super("org.objectweb.asm.benchmarks.AsmFactory");
+ }
+
+ /**
+ * Prepares the benchmark by creating a {@link Factory} for each library to be tested, and by
+ * loading some test data (i.e. some classes to read).
+ *
+ * @throws Exception if an error occurs.
+ */
+ @Setup
+ public void prepare() throws Exception {
+ asm4dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V4_0).newAsmBenchmark();
+ asm5dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
+ asm6dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
+ asm7dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V7_0).newAsmBenchmark();
+ asm8dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V8_0).newAsmBenchmark();
+ asm9dot0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V9_0).newAsmBenchmark();
+ asmCurrent = (Factory) new AsmBenchmarkFactory(AsmVersion.V_CURRENT).newAsmBenchmark();
+
+ // Check that the correct versions of ASM have been loaded.
+ if (!asm4dot0.getVersion().equals("ASM4")
+ || !asm5dot0.getVersion().equals("ASM5")
+ || !asm6dot0.getVersion().equals("ASM6")
+ || !asm7dot0.getVersion().equals("ASM7")
+ || !asm8dot0.getVersion().equals("ASM8")
+ || !asm9dot0.getVersion().equals("ASM9")
+ || !asmCurrent.getVersion().equals("ASM9")) {
+ throw new IllegalStateException();
+ }
+
+ prepareClasses();
+ }
+
+ @Benchmark
+ public void newClass_asm4_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm4dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asm5_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm5dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asm6_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm6dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asm7_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm7dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asm8_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm8dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asm9_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm9dot0.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClass_asmCurrent() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asmCurrent.newClass(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm4_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm4dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm5_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm5dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm6_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm6dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm7_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm7dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm8_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm8dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asm9_0() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asm9dot0.newClassNode(classFile));
+ }
+ }
+
+ @Benchmark
+ public void newClassNode_asmCurrent() {
+ for (byte[] classFile : classFiles) {
+ MemoryProfiler.keepReference(asmCurrent.newClassNode(classFile));
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java
new file mode 100644
index 00000000..68f405d6
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MemoryProfiler.java
@@ -0,0 +1,152 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.NotificationEmitter;
+import org.openjdk.jmh.infra.BenchmarkParams;
+import org.openjdk.jmh.infra.IterationParams;
+import org.openjdk.jmh.profile.InternalProfiler;
+import org.openjdk.jmh.results.AggregationPolicy;
+import org.openjdk.jmh.results.IterationResult;
+import org.openjdk.jmh.results.Result;
+import org.openjdk.jmh.results.ScalarResult;
+
+/**
+ * An {@link InternalProfiler} to measure the memory allocated per benchmark iteration.
+ *
+ * @author Eric Bruneton
+ */
+public class MemoryProfiler implements InternalProfiler {
+
+ private static final Logger LOGGER = Logger.getLogger(MemoryProfiler.class.getName());
+
+ private static Object[] references; // NOPMD(UnusedPrivateField): false positive.
+ private static int referenceCount;
+
+ private static final MemoryProbe memoryProbe = new MemoryProbe();
+ private static long usedMemoryBeforeIteration;
+
+ public static void keepReference(final Object reference) {
+ references[referenceCount++] = reference;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Adds used memory to the result.";
+ }
+
+ @Override
+ public void beforeIteration(
+ final BenchmarkParams benchmarkParams, final IterationParams iterationParams) {
+ if (!appliesToBenchmark(benchmarkParams)) {
+ return;
+ }
+ references = new Object[100000];
+ referenceCount = 0;
+ usedMemoryBeforeIteration = memoryProbe.getUsedMemory();
+ }
+
+ @Override
+ public Collection<? extends Result> afterIteration(
+ final BenchmarkParams benchmarkParams,
+ final IterationParams iterationParams,
+ final IterationResult result) {
+ if (!appliesToBenchmark(benchmarkParams)) {
+ return Collections.emptyList();
+ }
+ long usedMemoryAfterIteration = memoryProbe.getUsedMemory();
+ references = null;
+
+ long usedMemoryInIteration = usedMemoryAfterIteration - usedMemoryBeforeIteration;
+ double usedMemoryPerOp =
+ ((double) usedMemoryInIteration) / result.getMetadata().getMeasuredOps();
+ List<Result> results = new ArrayList<>();
+ results.add(new ScalarResult("+memory.used", usedMemoryPerOp, "bytes", AggregationPolicy.AVG));
+ return results;
+ }
+
+ private static boolean appliesToBenchmark(final BenchmarkParams benchmarkParams) {
+ return benchmarkParams.getBenchmark().contains("MemoryBenchmark");
+ }
+
+ static class MemoryProbe {
+
+ private static final int MAX_WAIT_MILLIS = 20 * 1000;
+
+ private final Object lock = new Object();
+
+ private int gcCount;
+
+ public MemoryProbe() {
+ for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
+ ((NotificationEmitter) gcBean)
+ .addNotificationListener((notification, handback) -> notifyGc(), null, null);
+ }
+ }
+
+ public long getUsedMemory() {
+ try {
+ systemGc(System.currentTimeMillis() + MAX_WAIT_MILLIS);
+ } catch (InterruptedException e) {
+ LOGGER.log(Level.WARNING, "Can't get used memory.");
+ return -1;
+ }
+ return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
+ }
+
+ private void notifyGc() {
+ synchronized (lock) {
+ gcCount++;
+ lock.notifyAll();
+ }
+ }
+
+ private void systemGc(final long deadline) throws InterruptedException {
+ synchronized (lock) {
+ System.gc(); // NOPMD(DoNotCallGarbageCollectionExplicitly): needed to measure used memory.
+ int previousGcCount = gcCount;
+ while (gcCount == previousGcCount) {
+ long timeout = deadline - System.currentTimeMillis();
+ if (timeout > 0) {
+ lock.wait(timeout);
+ } else {
+ throw new InterruptedException();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MozillaClassFileGenerator.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MozillaClassFileGenerator.java
new file mode 100644
index 00000000..61136ea2
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/MozillaClassFileGenerator.java
@@ -0,0 +1,61 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import org.mozilla.classfile.ByteCode;
+import org.mozilla.classfile.ClassFileWriter;
+
+/**
+ * A "Hello World!" class generator using the Mozilla ClassFile library.
+ *
+ * @author Eric Bruneton
+ */
+public class MozillaClassFileGenerator extends Generator {
+
+ @Override
+ public byte[] generateClass() {
+ ClassFileWriter classFileWriter =
+ new ClassFileWriter("HelloWorld", "java/lang/Object", "HelloWorld.java");
+
+ classFileWriter.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
+ classFileWriter.addLoadThis();
+ classFileWriter.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ classFileWriter.add(ByteCode.RETURN);
+ classFileWriter.stopMethod((short) 1);
+
+ classFileWriter.startMethod("main", "()V", ClassFileWriter.ACC_PUBLIC);
+ classFileWriter.add(ByteCode.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ classFileWriter.addPush("Hello world!");
+ classFileWriter.addInvoke(
+ ByteCode.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+ classFileWriter.add(ByteCode.RETURN);
+ classFileWriter.stopMethod((short) 1);
+
+ return classFileWriter.toByteArray();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/SerpAdapter.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/SerpAdapter.java
new file mode 100644
index 00000000..dc936c39
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/SerpAdapter.java
@@ -0,0 +1,61 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.benchmarks;
+
+import java.io.ByteArrayInputStream;
+import serp.bytecode.BCClass;
+import serp.bytecode.BCMethod;
+import serp.bytecode.Code;
+import serp.bytecode.Project;
+
+/**
+ * An {@link Adapter} implemented with the SERP library.
+ *
+ * @author Eric Bruneton
+ */
+public class SerpAdapter extends Adapter {
+
+ @Override
+ public byte[] readAndWrite(final byte[] classFile, final boolean computeMaxs) {
+ BCClass bcClass = new Project().loadClass(new ByteArrayInputStream(classFile));
+ bcClass.getDeclaredFields();
+ for (BCMethod bcMethod : bcClass.getDeclaredMethods()) {
+ Code code = bcMethod.getCode(false);
+ if (code != null) {
+ while (code.hasNext()) {
+ code.next();
+ }
+ if (computeMaxs) {
+ code.calculateMaxStack();
+ code.calculateMaxLocals();
+ }
+ }
+ }
+ return bcClass.toByteArray();
+ }
+}
diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java
new file mode 100644
index 00000000..badca26f
--- /dev/null
+++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java
@@ -0,0 +1,254 @@
+package org.objectweb.asm.benchmarks;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
+@State(Scope.Thread)
+public class TypeBenchmark extends AbstractBenchmark {
+
+ private ArrayList<String> descriptors;
+ private ArrayList<String> methodDescriptors;
+
+ public TypeBenchmark() {
+ super("org.objectweb.asm.benchmarks.Type");
+ }
+
+ @Setup
+ public void prepare() throws Exception {
+ prepareClasses();
+ descriptors = new ArrayList<>();
+ methodDescriptors = new ArrayList<>();
+ for (byte[] classFile : classFiles) {
+ new ClassReader(classFile).accept(new CollectTypesVisitor(), 0);
+ }
+ }
+
+ @Benchmark
+ public void getTypeFromDescriptor(final Blackhole blackhole) {
+ for (String descriptor : descriptors) {
+ blackhole.consume(Type.getType(descriptor));
+ }
+ for (String methodDescriptor : methodDescriptors) {
+ blackhole.consume(Type.getType(methodDescriptor));
+ }
+ }
+
+ @Benchmark
+ public void getArgumentsAndReturnTypesFromDescriptor(final Blackhole blackhole) {
+ for (String methodDescriptor : methodDescriptors) {
+ Type[] argumentTypes = Type.getArgumentTypes(methodDescriptor);
+ Type returnType = Type.getReturnType(methodDescriptor);
+ blackhole.consume(Type.getMethodType(returnType, argumentTypes));
+ }
+ }
+
+ @Benchmark
+ public void getArgumentsAndReturnSizeFromDescriptor(final Blackhole blackhole) {
+ for (String methodDescriptor : methodDescriptors) {
+ blackhole.consume(Type.getArgumentsAndReturnSizes(methodDescriptor));
+ }
+ }
+
+ class CollectTypesVisitor extends ClassVisitor {
+
+ AnnotationVisitor annotationVisitor =
+ new AnnotationVisitor(api) {
+
+ @Override
+ public void visitEnum(final String name, final String descriptor, final String value) {
+ descriptors.add(descriptor);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ descriptors.add(descriptor);
+ return this;
+ }
+ };
+
+ CollectTypesVisitor() {
+ super(/* latest */ Opcodes.ASM10_EXPERIMENTAL);
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name, final String descriptor) {
+ if (descriptor != null) {
+ methodDescriptors.add(descriptor);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ descriptors.add(descriptor);
+ return new FieldVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+ };
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ methodDescriptors.add(descriptor);
+ return new MethodVisitor(api) {
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter, final String descriptor, final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ descriptors.add(descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ methodDescriptors.add(descriptor);
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ methodDescriptors.add(descriptor);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ descriptors.add(descriptor);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+
+ @Override
+ public void visitLocalVariable(
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index) {
+ descriptors.add(descriptor);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(
+ final int typeRef,
+ final TypePath typePath,
+ final Label[] start,
+ final Label[] end,
+ final int[] index,
+ final String descriptor,
+ final boolean visible) {
+ descriptors.add(descriptor);
+ return annotationVisitor;
+ }
+ };
+ }
+ }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 00000000..0e67ce83
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,442 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+buildscript {
+ repositories { mavenCentral() }
+ dependencies { classpath 'org.netbeans.tools:sigtest-maven-plugin:1.5' }
+}
+
+plugins { id 'biz.aQute.bnd.builder' version '6.2.0' apply false }
+plugins { id 'com.github.sherter.google-java-format' version '0.9' apply false }
+plugins { id 'me.champeau.jmh' version '0.6.6' apply false }
+plugins { id 'org.sonarqube' version '3.3' apply false }
+
+description = 'ASM, a very small and fast Java bytecode manipulation framework'
+
+apply plugin: 'java-platform'
+dependencies {
+ constraints {
+ api project(':asm'), project(':asm-tree'), project(':asm-analysis')
+ api project(':asm-util'), project(':asm-commons')
+ }
+}
+
+allprojects {
+ group = 'org.ow2.asm'
+ version = '9.5' + (rootProject.hasProperty('release') ? '' : '-SNAPSHOT')
+}
+
+subprojects {
+ repositories { mavenCentral() }
+ apply plugin: 'java-library'
+ apply plugin: 'jacoco'
+ sourceCompatibility = '1.8'
+ targetCompatibility = '1.8'
+ test { useJUnitPlatform() }
+ ext.provides = [] // The provided java packages, e.g. ['org.objectweb.asm']
+ ext.requires = [] // The required Gradle projects, e.g. [':asm-test']
+ ext.transitiveRequires = { ->
+ return requires.collect{p ->
+ project(p).transitiveRequires().plus(project(p).provides[0])}.flatten()
+ }
+ ext.depends = [] // The external dependencies, e.g. ['junit:junit:4.12']
+ // Some external dependencies (such as Jacoco) depend transitively on ASM, and
+ // without this rule Gradle can mix ASM jars of different versions (e.g.
+ // asm-6.0.jar with the asm-tree.jar built locally).
+ configurations.all { resolutionStrategy { preferProjectModules() } }
+}
+
+// -----------------------------------------------------------------------------
+// Project descriptions
+// -----------------------------------------------------------------------------
+
+project(':asm') {
+ description = parent.description
+ provides = ['org.objectweb.asm', 'org.objectweb.asm.signature']
+}
+
+project(':asm-analysis') {
+ description = "Static code analysis API of ${parent.description}"
+ provides = ['org.objectweb.asm.tree.analysis']
+ requires = [':asm-tree']
+}
+
+project(':asm-commons') {
+ description = "Usefull class adapters based on ${parent.description}"
+ provides = ['org.objectweb.asm.commons']
+ requires = [':asm', ':asm-tree']
+ dependencies { testImplementation project(':asm-util') }
+}
+
+project(':asm-test') {
+ description = "Utilities for testing ${parent.description}"
+ provides = ['org.objectweb.asm.test']
+ depends = ['org.junit.jupiter:junit-jupiter-api:5.8.2',
+ 'org.junit.jupiter:junit-jupiter-params:5.8.2']
+}
+
+project(':asm-tree') {
+ description = "Tree API of ${parent.description}"
+ provides = ['org.objectweb.asm.tree']
+ requires = [':asm']
+}
+
+project(':asm-util') {
+ description = "Utilities for ${parent.description}"
+ provides = ['org.objectweb.asm.util']
+ requires = [':asm', ':asm-tree', ':asm-analysis']
+ dependencies { testImplementation 'org.codehaus.janino:janino:3.1.6' }
+}
+
+// Use "gradle benchmarks:jmh [-PjmhInclude='<regex>']" to run the benchmarks.
+project(':benchmarks') {
+ description = "Benchmarks for ${rootProject.description}"
+ apply plugin: 'me.champeau.jmh'
+ dependencies {
+ implementation files('libs/csg-bytecode-1.0.0.jar', 'libs/jclasslib.jar')
+ jmh project(':asm'), project(':asm-tree')
+ }
+ depends = [
+ 'kawa:kawa:1.7',
+ 'net.sf.jiapi:jiapi-reflect:0.5.2',
+ 'net.sourceforge.serp:serp:1.15.1',
+ 'org.apache.bcel:bcel:6.0',
+ 'org.aspectj:aspectjweaver:1.8.10',
+ 'org.cojen:cojen:2.2.5',
+ 'org.javassist:javassist:3.21.0-GA',
+ 'org.mozilla:rhino:1.7.7.1'
+ ]
+ ['4.0', '5.0.1', '6.0', '7.0', '8.0.1', '9.0'].each { version ->
+ configurations.create("asm${version}")
+ dependencies.add("asm${version}", "org.ow2.asm:asm:${version}@jar")
+ dependencies.add("asm${version}", "org.ow2.asm:asm-tree:${version}@jar")
+ task "asm${version}"(type: Copy) {
+ from configurations."asm${version}".collect { zipTree(it) }
+ into "${buildDir}/asm${version}"
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE // module-info.class
+ }
+ classes.dependsOn "asm${version}"
+ }
+ configurations.create('input-classes-java8')
+ dependencies.add('input-classes-java8', 'io.vavr:vavr:0.10.0@jar')
+ task copyInputClasses(type: Copy) {
+ from configurations.'input-classes-java8'.collect { zipTree(it) }
+ into "${buildDir}/input-classes-java8"
+ }
+ classes.dependsOn copyInputClasses
+ jmh {
+ jvmArgsAppend = ["-Duser.dir=${rootDir}"]
+ resultFormat = 'CSV'
+ profilers = ['org.objectweb.asm.benchmarks.MemoryProfiler']
+ if (rootProject.hasProperty('jmhInclude')) {
+ include = [jmhInclude]
+ }
+ }
+}
+
+project(':tools') {
+ description = "Tools used to build ${parent.description}"
+}
+
+project(':tools:retrofitter') {
+ description = "JDK 1.5 class retrofitter based on ${rootProject.description}"
+ sourceCompatibility = '1.9'
+ targetCompatibility = '1.9'
+ // TODO: this compiles asm twice (here and in :asm).
+ sourceSets.main.java.srcDirs += project(':asm').sourceSets.main.java.srcDirs
+}
+
+// -----------------------------------------------------------------------------
+// Project tasks creation and configuration
+// -----------------------------------------------------------------------------
+
+// All projects are checked with googleJavaFormat, Checkstyle and PMD,
+// and tested with :asm-test and JUnit.
+subprojects {
+ apply plugin: 'com.github.sherter.google-java-format'
+ googleJavaFormat.toolVersion = '1.15.0'
+ googleJavaFormat.exclude 'src/resources/java/**/*'
+
+ // Check the coding style with Checkstyle. Fail in case of error or warning.
+ apply plugin: 'checkstyle'
+ checkstyle.configFile = file("${rootDir}/tools/checkstyle.xml")
+ checkstyle.maxErrors = 0
+ checkstyle.maxWarnings = 0
+
+ // Check the code with PMD.
+ apply plugin: 'pmd'
+ pmd.ruleSets = []
+ pmd.ruleSetFiles = files("${rootDir}/tools/pmd.xml")
+ pmd.consoleOutput = true
+
+ dependencies {
+ requires.each { projectName -> api project(projectName) }
+ depends.each { artifactName -> api artifactName }
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2',
+ 'org.junit.jupiter:junit-jupiter-params:5.8.2'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
+ testImplementation project(':asm-test')
+ }
+
+ // Produce byte-for-byte reproducible archives.
+ tasks.withType(AbstractArchiveTask).configureEach {
+ preserveFileTimestamps = false
+ reproducibleFileOrder = true
+ dirMode = 0775
+ fileMode = 0664
+ }
+}
+
+// Configure the projects with a non-empty 'provides' property. They must be
+// checked for code coverage and backward compatibility, retrofited to Java 1.5,
+// and packaged with generated module-info classes.
+configure(subprojects.findAll { it.provides }) {
+ // Code coverage configuration.
+ jacoco.toolVersion = '0.8.8'
+ jacocoTestReport {
+ reports { xml.required = true }
+ classDirectories.setFrom(sourceSets.main.output.classesDirs)
+ }
+ jacocoTestCoverageVerification {
+ classDirectories.setFrom(sourceSets.main.output.classesDirs)
+ violationRules.rule { limit { minimum = 0.95; counter = 'INSTRUCTION' } }
+ }
+ check.dependsOn jacocoTestCoverageVerification
+
+ // Retrofit the code in-place to Java 1.5 and generate a module-info class
+ // from the code content, in compileJava.doLast.
+ if (name != 'asm-test') {
+ compileJava.dependsOn ':tools:retrofitter:classes'
+ compileJava.doLast {
+ def path = project(':tools:retrofitter').sourceSets.main.runtimeClasspath
+ def loader = new URLClassLoader(path.collect {f -> f.toURL()} as URL[])
+ def retrofitter =
+ loader.loadClass('org.objectweb.asm.tools.Retrofitter').newInstance()
+ def classes = sourceSets.main.output.classesDirs.singleFile
+ retrofitter.retrofit(classes, "${version}")
+ retrofitter.verify(classes, "${version}", provides, transitiveRequires())
+ }
+ }
+
+ // Create one backward compatibility checking task for each 'sigtest-*' file
+ // in test/resources, and make the 'check' task depend on all these tasks.
+ if (file('src/test/resources/').exists()) {
+ file('src/test/resources/').eachFileMatch(~/sigtest-.*/) { f ->
+ task "${f.name}"(dependsOn: 'classes') {
+ inputs.files(f, sourceSets.main.java)
+ outputs.file("${buildDir}/${f.name}")
+ doLast {
+ def sigtest = new com.sun.tdk.signaturetest.SignatureTest()
+ def args = ['-ApiVersion', version, '-Backward', '-Static',
+ '-Mode', 'bin', '-FileName', f, '-Classpath',
+ project(':tools').file('jdk8-api.jar').path + File.pathSeparator +
+ sourceSets.main.output.classesDirs.asPath, '-Package'] + provides
+ outputs.getFiles()[0].withPrintWriter { printWriter ->
+ sigtest.run(args as String[], printWriter, null)
+ }
+ if (!sigtest.isPassed()) throw new GradleException()
+ }
+ }
+ check.dependsOn f.name
+ }
+ // Define a task to create a sigtest file for the current version.
+ task "buildSigtest"(dependsOn: 'classes') {
+ inputs.files(sourceSets.main.java)
+ outputs.file("src/test/resources/sigtest-${version}.txt")
+ doLast {
+ def setup = new com.sun.tdk.signaturetest.Setup()
+ def args = ['-ApiVersion', version, '-FileName', outputs.getFiles()[0],
+ '-Classpath', project(':tools').file('jdk8-api.jar').path +
+ File.pathSeparator + sourceSets.main.output.classesDirs.asPath +
+ File.pathSeparator + sourceSets.main.compileClasspath.asPath,
+ '-Package'] + provides
+ setup.run(args as String[], new PrintWriter(System.err, true), null)
+ if (!setup.isPassed()) throw new GradleException()
+ }
+ }
+ }
+
+ // Apply the biz.aQute.bnd plugin to package the project as an OSGi bundle.
+ // Exclude the asm-test project (the DefaultPackage class prevents it from
+ // being a proper bundle).
+ if (name != 'asm-test') {
+ apply plugin: 'biz.aQute.bnd.builder'
+ jar.manifest.attributes(
+ '-classpath': sourceSets.main.output.classesDirs.asPath,
+ '-removeheaders': 'Bnd-LastModified,Build-By,Created-By,Include-Resource,\
+ Require-Capability,Tool',
+ 'Bundle-License': 'BSD-3-Clause;link=https://asm.ow2.io/LICENSE.txt',
+ 'Bundle-DocURL': 'http://asm.ow2.org',
+ 'Bundle-RequiredExecutionEnvironment': 'J2SE-1.5',
+ 'Bundle-SymbolicName': provides[0],
+ 'Export-Package': provides.collect{"${it};version=${version}"}.join(','),
+ 'Implementation-Title': project.description,
+ 'Implementation-Version': "${version}",
+ 'Module-Requires':
+ requires
+ .collect{"${project(it).provides[0]};transitive=true"}
+ .join(',')
+ )
+ } else {
+ jar.manifest.attributes(
+ 'Implementation-Title': project.description,
+ 'Implementation-Version': "${version}")
+ }
+
+ // Apply the SonarQube plugin to monitor the code quality of the project.
+ // Use with 'gradlew sonarqube -Dsonar.host.url=https://sonarqube.ow2.org'.
+ apply plugin: 'org.sonarqube'
+ sonarqube {
+ properties { property 'sonar.projectKey', "ASM:${project.name}" }
+ }
+
+ // Add a task to generate a private javadoc and add it as a dependency of the
+ // 'check' task.
+ task privateJavadoc(type: Javadoc) {
+ source = sourceSets.main.allJava
+ classpath = configurations.compileClasspath
+ destinationDir = file("${javadoc.destinationDir}-private")
+ options.memberLevel = JavadocMemberLevel.PRIVATE
+ options.addBooleanOption('Xdoclint:all,-missing', true)
+ }
+ check.dependsOn privateJavadoc
+
+ // Add tasks to generate the Javadoc and a source jar, to be uploaded to Maven
+ // together with the main jar (containing the compiled code).
+ task javadocJar(type: Jar, dependsOn: 'javadoc') {
+ from javadoc.destinationDir
+ classifier 'javadoc'
+ }
+ task sourcesJar(type: Jar, dependsOn: 'classes') {
+ from sourceSets.main.allSource
+ classifier 'sources'
+ }
+ java {
+ withJavadocJar()
+ withSourcesJar()
+ }
+}
+
+// Configure the root project, and those with a non-empty 'provides' property,
+// to be published in Maven with a POM.
+configure([rootProject] + subprojects.findAll { it.provides }) {
+ apply plugin: 'maven-publish'
+ apply plugin: 'signing'
+ publishing {
+ repositories {
+ maven {
+ def baseUrl = 'https://repository.ow2.org/nexus/'
+ def releasesUrl = baseUrl + 'service/local/staging/deploy/maven2'
+ def snapshotsUrl = baseUrl + 'content/repositories/snapshots'
+ name = 'nexus'
+ url = rootProject.hasProperty('release') ? releasesUrl : snapshotsUrl
+ credentials {
+ username System.env.NEXUS_USER_NAME
+ password System.env.NEXUS_PASSWORD
+ }
+ }
+ }
+ publications {
+ maven(MavenPublication) {
+ def isRoot = project == rootProject
+ artifactId (isRoot ? 'asm-bom' : project.name)
+ from (isRoot ? components.javaPlatform : components.java)
+ pom.withXml {
+ def parent = asNode().appendNode('parent')
+ parent.appendNode('groupId', 'org.ow2')
+ parent.appendNode('artifactId', 'ow2')
+ parent.appendNode('version', '1.5.1')
+ }
+ pom {
+ name = artifactId
+ description = project.description
+ packaging 'jar'
+ inceptionYear = '2000'
+ licenses {
+ license {
+ name = 'BSD-3-Clause'
+ url = 'https://asm.ow2.io/license.html'
+ }
+ }
+ url = 'http://asm.ow2.io/'
+ mailingLists {
+ mailingList {
+ name = 'ASM Users List'
+ subscribe = 'https://mail.ow2.org/wws/subscribe/asm'
+ post = 'asm@objectweb.org'
+ archive = 'https://mail.ow2.org/wws/arc/asm/'
+ }
+ mailingList {
+ name = 'ASM Team List'
+ subscribe = 'https://mail.ow2.org/wws/subscribe/asm-team'
+ post = 'asm-team@objectweb.org'
+ archive = 'https://mail.ow2.org/wws/arc/asm-team/'
+ }
+ }
+ issueManagement {
+ url = 'https://gitlab.ow2.org/asm/asm/issues'
+ }
+ scm {
+ connection = 'scm:git:https://gitlab.ow2.org/asm/asm/'
+ developerConnection = 'scm:git:https://gitlab.ow2.org/asm/asm/'
+ url = 'https://gitlab.ow2.org/asm/asm/'
+ }
+ developers {
+ developer {
+ name = 'Eric Bruneton'
+ id = 'ebruneton'
+ email = 'ebruneton@free.fr'
+ roles = ['Creator', 'Java Developer']
+ }
+ developer {
+ name = 'Eugene Kuleshov'
+ id = 'eu'
+ email = 'eu@javatx.org'
+ roles = ['Java Developer']
+ }
+ developer {
+ name = 'Remi Forax'
+ id = 'forax'
+ email = 'forax@univ-mlv.fr'
+ roles = ['Java Developer']
+ }
+ }
+ organization {
+ name = 'OW2'
+ url = 'http://www.ow2.org/'
+ }
+ }
+ }
+ }
+ }
+ signing {
+ required rootProject.hasProperty('release')
+ sign publishing.publications.maven
+ }
+ tasks.withType(GenerateModuleMetadata) { enabled = false }
+}
diff --git a/gradle/gradlew b/gradle/gradlew
new file mode 100755
index 00000000..2a07bd6b
--- /dev/null
+++ b/gradle/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradle/gradlew.bat b/gradle/gradlew.bat
new file mode 100644
index 00000000..fa40a7a6
--- /dev/null
+++ b/gradle/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..13372aef
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..4462a0e4
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Sep 24 11:45:36 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 00000000..bed9a5d9
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,40 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+
+rootProject.name = 'root'
+
+include(
+ 'asm',
+ 'asm-analysis',
+ 'asm-commons',
+ 'asm-test',
+ 'asm-tree',
+ 'asm-util',
+ 'benchmarks',
+ 'tools:retrofitter')
+
diff --git a/tools/checkstyle.xml b/tools/checkstyle.xml
new file mode 100644
index 00000000..2e7ed7cf
--- /dev/null
+++ b/tools/checkstyle.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+ "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+ "https://checkstyle.org/dtds/configuration_1_3.dtd">
+
+<module name="Checker">
+ <property name="charset" value="UTF-8" />
+ <property name="severity" value="warning" />
+ <property name="fileExtensions" value="java" />
+ <module name="TreeWalker">
+ <!-- Modules for the Google Java Style guide (expect those covered by google-java-format). -->
+ <module name="OuterTypeFilename" />
+ <module name="IllegalTokenText">
+ <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL" />
+ <property name="format"
+ value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)" />
+ <property name="message"
+ value="Use special escape sequence instead of octal value or Unicode escaped value." />
+ </module>
+ <module name="AvoidEscapedUnicodeCharacters">
+ <property name="allowEscapesForControlCharacters" value="true" />
+ <property name="allowByTailComment" value="true" />
+ <property name="allowNonPrintableEscapes" value="true" />
+ </module>
+ <module name="AvoidStarImport" />
+ <module name="OneTopLevelClass" />
+ <module name="EmptyBlock">
+ <property name="option" value="TEXT" />
+ <property name="tokens"
+ value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH" />
+ </module>
+ <module name="NeedBraces" />
+ <module name="MultipleVariableDeclarations" />
+ <module name="ArrayTypeStyle" />
+ <module name="MissingSwitchDefault" />
+ <module name="FallThrough" />
+ <module name="UpperEll" />
+ <module name="PackageName">
+ <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$" />
+ </module>
+ <module name="TypeName" />
+ <module name="MemberName">
+ <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$" />
+ </module>
+ <module name="ParameterName">
+ <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" />
+ </module>
+ <module name="LambdaParameterName">
+ <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" />
+ </module>
+ <module name="CatchParameterName">
+ <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" />
+ </module>
+ <module name="LocalVariableName">
+ <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" />
+ </module>
+ <module name="ClassTypeParameterName">
+ <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" />
+ </module>
+ <module name="MethodTypeParameterName">
+ <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" />
+ </module>
+ <module name="InterfaceTypeParameterName">
+ <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" />
+ </module>
+ <module name="NoFinalizer" />
+ <module name="AbbreviationAsWordInName">
+ <property name="ignoreFinal" value="false" />
+ <property name="allowedAbbreviationLength" value="1" />
+ </module>
+ <module name="OverloadMethodsDeclarationOrder" />
+ <module name="VariableDeclarationUsageDistance">
+ <property name="allowedDistance" value="4" />
+ </module>
+ <module name="NonEmptyAtclauseDescription" />
+ <module name="SummaryJavadoc">
+ <property name="forbiddenSummaryFragments"
+ value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )" />
+ </module>
+ <module name="JavadocParagraph" />
+ <module name="AtclauseOrder">
+ <property name="tagOrder" value="@param, @return, @throws, @deprecated" />
+ <property name="target"
+ value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF" />
+ </module>
+ <module name="JavadocMethod">
+ <property name="scope" value="public" />
+ <property name="allowMissingParamTags" value="true" />
+ <property name="allowMissingReturnTag" value="true" />
+ <property name="allowedAnnotations"
+ value="Override,BeforeEach,Test,ParameterizedTest,Setup,Benchmark" />
+ </module>
+ <module name="MethodName">
+ <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$" />
+ </module>
+ <module name="SingleLineJavadoc">
+ <property name="ignoredTags" value="@code,@link,@literal" />
+ <property name="ignoreInlineTags" value="false" />
+ </module>
+ <module name="EmptyCatchBlock">
+ <property name="exceptionVariableName" value="expected" />
+ </module>
+
+ <!-- Additional modules, not related to the Google Java Style guide. -->
+ <module name="AvoidNestedBlocks">
+ <property name="allowInSwitchCase" value="true" />
+ </module>
+ <module name="HideUtilityClassConstructor" />
+ <module name="InnerTypeLast" />
+ <module name="InterfaceIsType" />
+ <module name="MutableException" />
+ <module name="ThrowsCount" />
+ <module name="CovariantEquals" />
+ <module name="DeclarationOrder">
+ <property name="ignoreModifiers" value="true" />
+ </module>
+ <module name="DefaultComesLast" />
+ <module name="EmptyStatement" />
+ <module name="EqualsHashCode" />
+ <module name="ExplicitInitialization" />
+ <module name="IllegalCatch" />
+ <module name="IllegalThrows" />
+ <module name="IllegalType">
+ <property name="illegalClassNames"
+ value="ArrayList,LinkedList,HashSet,TreeSet,LinkedHashSet,HashMap,TreeMap,LinkedHashMap" />
+ <property name="memberModifiers" value="LITERAL_PUBLIC,LITERAL_PROTECTED" />
+ </module>
+ <module name="JavadocStyle" />
+ <module name="ModifiedControlVariable" />
+ <module name="NoClone" />
+ <module name="SimplifyBooleanExpression" />
+ <module name="SimplifyBooleanReturn" />
+ <module name="StringLiteralEquality" />
+ <module name="FinalClass" />
+ <module name="FinalParameters" />
+
+ <!-- Module allowing to suppress warnings with DontCheck(...) comments. -->
+ <module name="SuppressWithNearbyCommentFilter">
+ <property name="commentFormat" value="DontCheck\((\w+)\)" />
+ <property name="checkFormat" value="$1" />
+ <property name="influenceFormat" value="1" />
+ </module>
+ <module name="SuppressWithNearbyCommentFilter">
+ <property name="commentFormat" value="DontCheck\(IllegalCatch\)" />
+ <property name="checkFormat" value="IllegalCatch" />
+ <property name="influenceFormat" value="-1" />
+ </module>
+ </module>
+</module>
diff --git a/tools/jdk8-api.jar b/tools/jdk8-api.jar
new file mode 100644
index 00000000..6cf6ac5f
--- /dev/null
+++ b/tools/jdk8-api.jar
Binary files differ
diff --git a/tools/pmd.xml b/tools/pmd.xml
new file mode 100644
index 00000000..a4d73723
--- /dev/null
+++ b/tools/pmd.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+
+<ruleset name="ASM" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0
+ https://pmd.sourceforge.net/ruleset_2_0_0.xsd">
+ <description>PMD rules for ASM</description>
+
+ <rule ref="category/java/bestpractices.xml">
+ <!-- Core API is using this on purpose. -->
+ <exclude name="AbstractClassWithoutAbstractMethod" />
+ <!-- Does not work, too many false positives. -->
+ <exclude name="AccessorMethodGeneration" />
+ <!-- Already covered with Checkstyle 'FinalParameters' rule. -->
+ <exclude name="AvoidReassigningParameters" />
+ <!-- Used for legitimate purposes in some Writer classes. -->
+ <exclude name="AvoidStringBufferField" />
+ <!-- Not relevant for ASM. -->
+ <exclude name="AvoidUsingHardCodedIP" />
+ <exclude name="CheckResultSet" />
+ <!-- Already covered with Checkstyle 'InterfaceIsType' rule. -->
+ <exclude name="ConstantsInInterface" />
+ <!-- Already covered with Checkstyle 'DefaultComesLast' rule. -->
+ <exclude name="DefaultLabelNotLastInSwitchStmt" />
+ <!-- Not relevant for ASM (no logging and using JUnit 5). -->
+ <exclude name="GuardLogStatement" />
+ <exclude name="JUnit4SuitesShouldUseSuiteAnnotation" />
+ <exclude name="JUnit4TestShouldUseAfterAnnotation" />
+ <exclude name="JUnit4TestShouldUseBeforeAnnotation" />
+ <exclude name="JUnit4TestShouldUseTestAnnotation" />
+ <!-- Would give too verbose code. -->
+ <exclude name="JUnitAssertionsShouldIncludeMessage" />
+ <exclude name="JUnitTestContainsTooManyAsserts" />
+ <!-- Not relevant for ASM (using JUnit 5). -->
+ <exclude name="JUnitUseExpected" />
+ <!-- Already covered with Checkstyle 'IllegalType' rule. -->
+ <exclude name="LooseCoupling" />
+ <!-- Already covered with google-java-format. -->
+ <exclude name="OneDeclarationPerLine" />
+ <!-- Actually not a best practice. -->
+ <exclude name="LiteralsFirstInComparisons" />
+ <!-- Already covered with Checkstyle 'MissingSwitchDefault' rule. -->
+ <exclude name="SwitchStmtsShouldHaveDefault" />
+ <!-- Already covered with google-java-format. -->
+ <exclude name="UnusedImports" />
+ <!-- Too many false positives. -->
+ <exclude name="UseVarargs" />
+ </rule>
+ <rule ref="category/java/bestpractices.xml/ArrayIsStoredDirectly">
+ <properties>
+ <property name="violationSuppressXPath"
+ value="//MethodDeclaration[@Private='true' or
+ @PackagePrivate='true']" />
+ </properties>
+ </rule>
+ <rule ref="category/java/bestpractices.xml/MethodReturnsInternalArray">
+ <properties>
+ <property name="violationSuppressXPath"
+ value="//MethodDeclaration[@Private='true' or
+ @PackagePrivate='true']" />
+ </properties>
+ </rule>
+ <rule ref="category/java/bestpractices.xml/ForLoopVariableCount">
+ <properties>
+ <property name="maximumVariables" value="2" />
+ </properties>
+ </rule>
+
+ <rule ref="category/java/errorprone.xml">
+ <!-- Do not want this rule. -->
+ <exclude name="AssignmentInOperand" />
+ <!-- Not relevant for ASM (no BigDecimal). -->
+ <exclude name="AvoidDecimalLiteralsInBigDecimalConstructor" />
+ <!-- Do not want these rules. -->
+ <exclude name="AvoidDuplicateLiterals" />
+ <exclude name="AvoidFieldNameMatchingMethodName" />
+ <exclude name="AvoidLiteralsInIfCondition" />
+ <!-- Not relevant for ASM (no Java Beans). -->
+ <exclude name="BeanMembersShouldSerialize" />
+ <!-- Too many false positives. -->
+ <exclude name="CompareObjectsWithEquals" />
+ <!-- Does not work, too many false positives. -->
+ <exclude name="DataflowAnomalyAnalysis" />
+ <!-- Not relevant for ASM. -->
+ <exclude name="DoNotHardCodeSDCard" />
+ <exclude name="DontImportSun" />
+ <!-- Already covered with Checkstyle 'NoFinalizer' rule. -->
+ <exclude name="FinalizeDoesNotCallSuperFinalize" />
+ <exclude name="FinalizeOnlyCallsSuperFinalize" />
+ <exclude name="FinalizeOverloaded" />
+ <exclude name="FinalizeShouldBeProtected" />
+ <!-- Not relevant for ASM (no logging and using JUnit 5). -->
+ <exclude name="JUnitSpelling" />
+ <exclude name="JUnitStaticSuite" />
+ <exclude name="LoggerIsNotStaticFinal" />
+ <exclude name="MoreThanOneLogger" />
+ <!-- Needed to implement custom data structures such as linked lists. -->
+ <exclude name="NullAssignment" />
+ <!-- Not relevant for ASM (no logging, no dates, no EJB). -->
+ <exclude name="ProperLogger" />
+ <exclude name="SimpleDateFormatNeedsLocale" />
+ <exclude name="StaticEJBFieldShouldBeFinal" />
+ <exclude name="UseProperClassLoader" />
+ </rule>
+ <rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull">
+ <properties>
+ <property name="violationSuppressXPath"
+ value="//MethodDeclaration[@Private='true']"/>
+ </properties>
+ </rule>
+
+ <rule ref="category/java/performance.xml">
+ <!-- Too many false positives. -->
+ <exclude name="AvoidInstantiatingObjectsInLoops" />
+ <!-- Shorts can be decrease memory use, without decreasing performance. -->
+ <exclude name="AvoidUsingShortType" />
+ <!-- Not relevant for ASM (no BigInteger). -->
+ <exclude name="BigIntegerInstantiation" />
+ <!-- Does not work, too many false positives. -->
+ <exclude name="InsufficientStringBufferDeclaration" />
+ </rule>
+</ruleset>
+
diff --git a/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java
new file mode 100644
index 00000000..43002cea
--- /dev/null
+++ b/tools/retrofitter/src/main/java/org/objectweb/asm/tools/Retrofitter.java
@@ -0,0 +1,491 @@
+// ASM: a very small and fast Java bytecode manipulation framework
+// Copyright (c) 2000-2011 INRIA, France Telecom
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+package org.objectweb.asm.tools;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.toSet;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.lang.module.ModuleDescriptor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+import java.util.zip.GZIPInputStream;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A tool to transform classes in order to make them compatible with Java 1.5, and to check that
+ * they use only the JDK 1.5 API and JDK 1.5 class file features. The original classes can either be
+ * transformed "in place", or be copied first to destination directory and transformed here (leaving
+ * the original classes unchanged).
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class Retrofitter {
+
+ /** The name of the module-info file. */
+ private static final String MODULE_INFO = "module-info.class";
+
+ /** The name of the java.base module. */
+ private static final String JAVA_BASE_MODULE = "java.base";
+
+ /**
+ * The fields and methods of the JDK 1.5 API. Each string has the form
+ * "&lt;owner&gt;&lt;name&gt;&lt;descriptor&gt;".
+ */
+ private final HashSet<String> jdkApi = new HashSet<>();
+
+ /**
+ * The class hierarchy of the JDK 1.5 API. Maps each class name to the name of its super class.
+ */
+ private final HashMap<String, String> jdkHierarchy = new HashMap<>();
+
+ /** The internal names of the packages exported by the retrofitted classes. */
+ private final HashSet<String> exports = new HashSet<>();
+
+ /** The internal names of the packages imported by the retrofitted classes. */
+ private final HashSet<String> imports = new HashSet<>();
+
+ /**
+ * Transforms the class files in the given directory, in place, in order to make them compatible
+ * with the JDK 1.5. Also generates a module-info class in this directory, with the given module
+ * version.
+ *
+ * @param args a directory containing compiled classes and the ASM release version.
+ * @throws IOException if a file can't be read or written.
+ */
+ public static void main(final String[] args) throws IOException {
+ if (args.length == 2) {
+ new Retrofitter().retrofit(new File(args[0]), args[1]);
+ } else {
+ System.err.println("Usage: Retrofitter <classes directory> <ASM release version>"); // NOPMD
+ }
+ }
+
+ /**
+ * Transforms the class files in the given directory, in place, in order to make them compatible
+ * with the JDK 1.5. Also generates a module-info class in this directory, with the given module
+ * version.
+ *
+ * @param classesDir a directory containing compiled classes.
+ * @param version the module-info version.
+ * @throws IOException if a file can't be read or written.
+ */
+ public void retrofit(final File classesDir, final String version) throws IOException {
+ for (File classFile : getAllClasses(classesDir, new ArrayList<File>())) {
+ ClassReader classReader = new ClassReader(Files.newInputStream(classFile.toPath()));
+ ClassWriter classWriter = new ClassWriter(0);
+ classReader.accept(new ClassRetrofitter(classWriter), ClassReader.SKIP_FRAMES);
+ Files.write(classFile.toPath(), classWriter.toByteArray());
+ }
+ generateModuleInfoClass(classesDir, version);
+ }
+
+ /**
+ * Verify that the class files in the given directory only use JDK 1.5 APIs, and that a
+ * module-info class is present with the expected content.
+ *
+ * @param classesDir a directory containing compiled classes.
+ * @param expectedVersion the expected module-info version.
+ * @param expectedExports the expected module-info exported packages.
+ * @param expectedRequires the expected module-info required modules.
+ * @throws IOException if a file can't be read.
+ * @throws IllegalArgumentException if the module-info class does not have the expected content.
+ */
+ public void verify(
+ final File classesDir,
+ final String expectedVersion,
+ final List<String> expectedExports,
+ final List<String> expectedRequires)
+ throws IOException {
+ if (jdkApi.isEmpty()) {
+ readJdkApi();
+ }
+ for (File classFile : getAllClasses(classesDir, new ArrayList<File>())) {
+ if (!classFile.getName().equals(MODULE_INFO)) {
+ new ClassReader(Files.newInputStream(classFile.toPath())).accept(new ClassVerifier(), 0);
+ }
+ }
+ verifyModuleInfoClass(
+ classesDir,
+ expectedVersion,
+ new HashSet<String>(expectedExports),
+ Stream.concat(expectedRequires.stream(), Stream.of(JAVA_BASE_MODULE)).collect(toSet()));
+ }
+
+ private List<File> getAllClasses(final File file, final List<File> allClasses)
+ throws IOException {
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ if (children == null) {
+ throw new IOException("Unable to read files of " + file);
+ }
+ for (File child : children) {
+ getAllClasses(child, allClasses);
+ }
+ } else if (file.getName().endsWith(".class")) {
+ allClasses.add(file);
+ }
+ return allClasses;
+ }
+
+ private void generateModuleInfoClass(final File dstDir, final String version) throws IOException {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(Opcodes.V9, Opcodes.ACC_MODULE, "module-info", null, null, null);
+ ArrayList<String> moduleNames = new ArrayList<>();
+ for (String exportName : exports) {
+ if (isAsmModule(exportName)) {
+ moduleNames.add(exportName);
+ }
+ }
+ if (moduleNames.size() != 1) {
+ throw new IllegalArgumentException("Module name can't be infered from classes");
+ }
+ ModuleVisitor moduleVisitor =
+ classWriter.visitModule(moduleNames.get(0).replace('/', '.'), Opcodes.ACC_OPEN, version);
+
+ for (String importName : imports) {
+ if (isAsmModule(importName) && !exports.contains(importName)) {
+ moduleVisitor.visitRequire(importName.replace('/', '.'), Opcodes.ACC_TRANSITIVE, null);
+ }
+ }
+ moduleVisitor.visitRequire(JAVA_BASE_MODULE, Opcodes.ACC_MANDATED, null);
+
+ for (String exportName : exports) {
+ moduleVisitor.visitExport(exportName, 0);
+ }
+ moduleVisitor.visitEnd();
+ classWriter.visitEnd();
+ Files.write(Path.of(dstDir.getAbsolutePath(), MODULE_INFO), classWriter.toByteArray());
+ }
+
+ private void verifyModuleInfoClass(
+ final File dstDir,
+ final String expectedVersion,
+ final Set<String> expectedExports,
+ final Set<String> expectedRequires)
+ throws IOException {
+ ModuleDescriptor module =
+ ModuleDescriptor.read(Files.newInputStream(Path.of(dstDir.getAbsolutePath(), MODULE_INFO)));
+ String version = module.version().map(ModuleDescriptor.Version::toString).orElse("");
+ if (!version.equals(expectedVersion)) {
+ throw new IllegalArgumentException(
+ format("Wrong module-info version '%s' (expected '%s')", version, expectedVersion));
+ }
+ Set<String> exports =
+ module.exports().stream().map(ModuleDescriptor.Exports::source).collect(toSet());
+ if (!exports.equals(expectedExports)) {
+ throw new IllegalArgumentException(
+ format("Wrong module-info exports %s (expected %s)", exports, expectedExports));
+ }
+ Set<String> requires =
+ module.requires().stream().map(ModuleDescriptor.Requires::name).collect(toSet());
+ if (!requires.equals(expectedRequires)) {
+ throw new IllegalArgumentException(
+ format("Wrong module-info requires %s (expected %s)", requires, expectedRequires));
+ }
+ }
+
+ private static boolean isAsmModule(final String packageName) {
+ return packageName.startsWith("org/objectweb/asm")
+ && !packageName.equals("org/objectweb/asm/signature");
+ }
+
+ private void readJdkApi() throws IOException {
+ try (InputStream inputStream =
+ new GZIPInputStream(
+ Retrofitter.class.getClassLoader().getResourceAsStream("jdk1.5.0.12.txt.gz"));
+ BufferedReader reader = new LineNumberReader(new InputStreamReader(inputStream))) {
+ while (true) {
+ String line = reader.readLine();
+ if (line != null) {
+ if (line.startsWith("class")) {
+ String className = line.substring(6, line.lastIndexOf(' '));
+ String superClassName = line.substring(line.lastIndexOf(' ') + 1);
+ jdkHierarchy.put(className, superClassName);
+ } else {
+ jdkApi.add(line);
+ }
+ } else {
+ break;
+ }
+ }
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+
+ /** A ClassVisitor that retrofits classes to 1.5 version. */
+ class ClassRetrofitter extends ClassVisitor {
+
+ public ClassRetrofitter(final ClassVisitor classVisitor) {
+ super(/* latest api =*/ Opcodes.ASM8, classVisitor);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ addPackageReferences(Type.getObjectType(name), /* export = */ true);
+ super.visit(Opcodes.V1_5, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final Object value) {
+ addPackageReferences(Type.getType(descriptor), /* export = */ false);
+ return super.visitField(access, name, descriptor, signature, value);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ addPackageReferences(Type.getType(descriptor), /* export = */ false);
+ return new MethodVisitor(
+ api, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ addPackageReferences(Type.getType(descriptor), /* export = */ false);
+ super.visitFieldInsn(opcode, owner, name, descriptor);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ addPackageReferences(Type.getType(descriptor), /* export = */ false);
+ // Remove the addSuppressed() method calls generated for try-with-resources statements.
+ // This method is not defined in JDK1.5.
+ if (owner.equals("java/lang/Throwable")
+ && name.equals("addSuppressed")
+ && descriptor.equals("(Ljava/lang/Throwable;)V")) {
+ visitInsn(Opcodes.POP2);
+ } else {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ addPackageReferences(Type.getObjectType(type), /* export = */ false);
+ super.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+ addPackageReferences(Type.getType(descriptor), /* export = */ false);
+ super.visitMultiANewArrayInsn(descriptor, numDimensions);
+ }
+
+ @Override
+ public void visitTryCatchBlock(
+ final Label start, final Label end, final Label handler, final String type) {
+ if (type != null) {
+ addPackageReferences(Type.getObjectType(type), /* export = */ false);
+ }
+ super.visitTryCatchBlock(start, end, handler, type);
+ }
+ };
+ }
+
+ private void addPackageReferences(final Type type, final boolean export) {
+ switch (type.getSort()) {
+ case Type.ARRAY:
+ addPackageReferences(type.getElementType(), export);
+ break;
+ case Type.METHOD:
+ for (Type argumentType : type.getArgumentTypes()) {
+ addPackageReferences(argumentType, export);
+ }
+ addPackageReferences(type.getReturnType(), export);
+ break;
+ case Type.OBJECT:
+ String internalName = type.getInternalName();
+ int lastSlashIndex = internalName.lastIndexOf('/');
+ if (lastSlashIndex != -1) {
+ (export ? exports : imports).add(internalName.substring(0, lastSlashIndex));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * A ClassVisitor checking that a class uses only JDK 1.5 class file features and the JDK 1.5 API.
+ */
+ class ClassVerifier extends ClassVisitor {
+
+ /** The internal name of the visited class. */
+ String className;
+
+ /** The name of the currently visited method. */
+ String currentMethodName;
+
+ public ClassVerifier() {
+ // Make sure use we don't use Java 9 or higher classfile features.
+ // We also want to make sure we don't use Java 6, 7 or 8 classfile
+ // features (invokedynamic), but this can't be done in the same way.
+ // Instead, we use manual checks below.
+ super(Opcodes.ASM4, null);
+ }
+
+ @Override
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces) {
+ if ((version & 0xFFFF) > Opcodes.V1_5) {
+ throw new IllegalArgumentException(format("ERROR: %d version is newer than 1.5", version));
+ }
+ className = name;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String descriptor,
+ final String signature,
+ final String[] exceptions) {
+ currentMethodName = name + descriptor;
+ MethodVisitor methodVisitor =
+ super.visitMethod(access, name, descriptor, signature, exceptions);
+ return new MethodVisitor(Opcodes.ASM4, methodVisitor) {
+ @Override
+ public void visitFieldInsn(
+ final int opcode, final String owner, final String name, final String descriptor) {
+ check(owner, name);
+ }
+
+ @Override
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String descriptor,
+ final boolean isInterface) {
+ check(owner, name + descriptor);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object value) {
+ if (value instanceof Type) {
+ int sort = ((Type) value).getSort();
+ if (sort == Type.METHOD) {
+ throw new IllegalArgumentException(
+ format(
+ "ERROR: ldc with a MethodType called in %s %s is not available in JDK 1.5",
+ className, currentMethodName));
+ }
+ } else if (value instanceof Handle) {
+ throw new IllegalArgumentException(
+ format(
+ "ERROR: ldc with a MethodHandle called in %s %s is not available in JDK 1.5",
+ className, currentMethodName));
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ final String name,
+ final String descriptor,
+ final Handle bootstrapMethodHandle,
+ final Object... bootstrapMethodArguments) {
+ throw new IllegalArgumentException(
+ format(
+ "ERROR: invokedynamic called in %s %s is not available in JDK 1.5",
+ className, currentMethodName));
+ }
+ };
+ }
+
+ /**
+ * Checks whether or not a field or method is defined in the JDK 1.5 API.
+ *
+ * @param owner A class name.
+ * @param member A field name or a method name and descriptor.
+ */
+ private void check(final String owner, final String member) {
+ if (owner.startsWith("java/")) {
+ String currentOwner = owner;
+ while (currentOwner != null) {
+ if (jdkApi.contains(currentOwner + ' ' + member)) {
+ return;
+ }
+ currentOwner = jdkHierarchy.get(currentOwner);
+ }
+ throw new IllegalArgumentException(
+ format(
+ "ERROR: %s %s called in %s %s is not defined in the JDK 1.5 API",
+ owner, member, className, currentMethodName));
+ }
+ }
+ }
+}
diff --git a/tools/retrofitter/src/main/resources/jdk1.5.0.12.txt.gz b/tools/retrofitter/src/main/resources/jdk1.5.0.12.txt.gz
new file mode 100644
index 00000000..a3141e17
--- /dev/null
+++ b/tools/retrofitter/src/main/resources/jdk1.5.0.12.txt.gz
Binary files differ